本来只打算写Tomcat集群部署,简化Apache和Tomcat整合过程的。后来想了想,这样不便于没有用过Apache的朋友来学习本文内容。于是干脆加大篇幅,让对Apache不了解的朋友能对Apache有个初步的认识,阿帕奇。
如果对集群概念不了解,可以看一下之前写的一篇:WebLogic部署集群和代理服务器 这篇对集群的概念解释的比较细致,与weblogic集群的不同之处在于,它对各个子服务器上应用的部署,是由weblogic容器自动完成的。而tomcat则需要手动去拷贝项目。
一、负载均衡网络拓扑图。
一、Apache服务器的安装及配置。
1.先网上下载Apache服务器安装版,双击安装,直接下一步下一步不需要做任何配置。
2.安装好以后打开安装目录,找到conf目录打开
1.手动创建两个文件
#================从这里复制================
#加载mod_jk Module 注意文件名根据实际情况而填
LoadModule jk_module modules/mod_jk-1.2.31-httpd-2.2.3.so
#指定 workers.properties文件路径
JkWorkersFile conf/workers.properties
#指定那些请求交给tomcat处理,"controller"为在workers.propertise里指定的负载分配控制器
JkMount /*.do controller
JkMount /*WEB-INF controller
JkMount /*j_spring_security_check controller
JkMount /*.action controller
JkMount /servlet/* controller
JkMount /*.jsp controller
JkMount /*.do controller
JkMount /*.action controller
JkMount /* controller
#================文件内容================
#================从这里复制================
#server 列表
worker.list = controller,tomcat1,tomcat2
#========tomcat1========
worker.tomcat1.port=9101
worker.tomcat1.host=localhost
worker.tomcat1.type=ajp13
worker.tomcat1.lbfactor = 1
#========tomcat2========
worker.tomcat2.port=9102
worker.tomcat2.host=localhost
worker.tomcat2.type=ajp13
worker.tomcat2.lbfactor = 1
#========controller,负载均衡控制器========
worker.controller.type=lb
worker.controller.balanced_workers=tomcat1,tomcat2
worker.controller.sticky_session=0
#================到这里截止================
2.修改httpd.conf文件内容
打开httpd.conf文件,最后一行加上:Include conf/mod_jk.conf
Apache默认端口是80,如果需要改端口直接找到该文件下Listen 80字段,把这个80改掉就可以了。
3.添加mod_jk-1.2.31-httpd-2.2.3.so插件
下载mod_jk-1.2.31-httpd-2.2.3.so文件添加到modules文件夹下。这个so文件是配置负载均衡必须要用到的插件。
配到这里Apache这块就不用去动了。
三、Tomcat服务器的安装及配置。
1.下载tomcat后直接解压得到。
2.打开conf文件夹下的server.xml文件修改以下内容保证两台tomcat的相应端口不冲突:
第一处:port
<Server port="9011" shutdown="SHUTDOWN">
第二处:port、redirectPort 注意编码格式需设置成gbk,否则存在乱码问题
<Connector port="9001" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="9441"
URIEncoding="GBK"/>
第三处:port对应Apache配置文件中配置的port、redirectPort,注意编码
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
替换成:
URIEncoding="GBK
minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true" connectionTimeout="20000"
acceptCount="300" maxThreads="300" maxProcessors="1000" minProcessors="5"
useURIValidationHack="false" ompression="on" compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
/>
第四处:jvmRoute对应Apache配置文件中配置的tomcat名
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
第五处:只改蓝色标记的port
在<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">下面添加以下字段:
channelSendOptions="6">
<Manager className="org.apache.catalina.ha.session.BackupManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"
mapSendOptions="6"/>
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
bind="127.0.0.1"
address="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto"
port="4001"
selectorTimeout="100"
maxThreads="6"/>
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender" timeout="60000"/>
</Sender>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
四、应用部署及运行
1.将项目拷贝到所有tomcat下的webapps文件夹下。
2.找到tomcat服务器bin目录下的android实现gif图与文字混排 - 杰瑞教育 阅读原文» 我们在进行qq聊天的时候发送表情,但这些表情都是并不是静态的,更多的是动态图,gif图,那么如何在android客户端显示动态gif图呢。 在github上找到了这样一种方法,Github地址https://github.com/TracyZhangLei/android-gif-demo 由于我是截图,所以看不到动态效果,大家可以自己下载看一下。 我们首先来看一下该开源项目的代码。该开源项目主要是通过自定义一个Adapter-------chatAdapter,在ChatAdapter每一条的setText属性中使用了自定义的方法convertNormalStringToSpannableString convertNormalStringToSpannableString方法的返回值是SpannableString 我们首先来了解一下什么是SpannableString TextView通常用来显示普通文本,但是有时候需要对其中某些文本进行样式、事件方面的设置。Android系统通过SpannableString类来对指定文本进行相关处理,也就是说我们想要实现文字加动态表情的实现就要通过SpannableString这个类来实现。 首先将我们传入的message转化成SpannableString类,然后看一下传入的值是否符合我们一开始写好的正则表达式EMOTION_URL 如果符合的话 我们取group(0) 附:group是针对()来说的,group(0)就是指的整个串,group(1)指的是第一个括号里的东西,group(2)指的第二个括号里的东西。 子表达式和起始位置和结束位置的差小于8,也就是符合我们的要求。调用FaceManager中的getFaceId方法 找到我们用Map进行存储的表情 如果表情存在的话利用一个弱引用(WeakReference)把自定义的AnimatedImageSpan进行处理,使AnimatedImageSpan不那么的消耗内存,在UpdateListener中利用postInvalidate刷新界面。最后把SpannableString的setSpan方法,三个参数分别是要放进去的span ,起始位置,结束位置,flag标志。 关于flag: Spanned.SPAN_EXCLUSIVE_EXCLUSIVE, 这是在 setSpan 时需要指定的 flag,它是用来标识在 Span 范围内的文本前后输入新的字符时是否把它们也应用这个效果。分别有 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE(前后都不包括)、 Spanned.SPAN_INCLUSIVE_EXCLUSIVE(前面包括,后面不包括)、 Spanned.SPAN_EXCLUSIVE_INCLUSIVE(前面不包括,后面包括)、 Spanned.SPAN_INCLUSIVE_INCLUSIVE(前后都包括)。 最后将SpannableString返回,实现动态图文混排。 关于自定义的AnimatedImageSpan如下:
SpannableString value = SpannableString.valueOf(message);
Matcher localMatcher = EMOTION_URL.matcher(value);
while (localMatcher.find()) {
String str2 = localMatcher.group(0);
int k = localMatcher.start();
int m = localMatcher.end();
if (m - k < 8) {
int face = fm.getFaceId(str2);
if(-1!=face){//wrapping with weakReference
WeakReference<AnimatedImageSpan> localImageSpanRef = new WeakReference<AnimatedImageSpan>(new AnimatedImageSpan(new AnimatedGifDrawable(cxt.getResources().openRawResource(face), new AnimatedGifDrawable.UpdateListener() {
@Override
public void update() {//update the textview
tv.postInvalidate();
}
})));
value.setSpan(localImageSpanRef.get(), k, m, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
}
}
}
return value;
}
if(mFaceMap.containsKey(faceStr)){
return mFaceMap.get(faceStr);
}
return -1;
}
private Drawable mDrawable;
public AnimatedImageSpan(Drawable d) {
super();
mDrawable = d;
// Use handler for 'ticks' to proceed to next frame
final Handler mHandler = new Handler();
mHandler.post(new Runnable() {
public void run() {
((AnimatedGifDrawable)mDrawable).nextFrame();
// Set next with a delay depending on the duration for this frame
mHandler.postDelayed(this, ((AnimatedGifDrawable)mDrawable).getFrameDuration());
}
});
}
@Override
public Drawable getDrawable() {
return ((AnimatedGifDrawable)mDrawable).getDrawable();
}
@Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
Drawable d = getDrawable();
Rect rect = d.getBounds();
if (fm != null阅读更多内容
没有评论:
发表评论