2015年6月10日星期三

Apache+Tomcat部署负载均衡(或集群) - RUN_TIME

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
Apache+Tomcat部署负载均衡(或集群) - RUN_TIME  阅读原文»

本来只打算写Tomcat集群部署,简化Apache和Tomcat整合过程的。后来想了想,这样不便于没有用过Apache的朋友来学习本文内容。于是干脆加大篇幅,让对Apache不了解的朋友能对Apache有个初步的认识,阿帕奇。

如果对集群概念不了解,可以看一下之前写的一篇:WebLogic部署集群和代理服务器 这篇对集群的概念解释的比较细致,与weblogic集群的不同之处在于,它对各个子服务器上应用的部署,是由weblogic容器自动完成的。而tomcat则需要手动去拷贝项目。

一、负载均衡网络拓扑图。

一、Apache服务器的安装及配置。

1.先网上下载Apache服务器安装版,双击安装,直接下一步下一步不需要做任何配置。

2.安装好以后打开安装目录,找到conf目录打开

1.手动创建两个文件

mod_jk.conf
#================从这里复制================
#加载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
#================文件内容================

workers.properties

#================从这里复制================
#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">

第二处:portredirectPort 注意编码格式需设置成gbk,否则存在乱码问题

<Connector port="9001" protocol="HTTP/1.1"

connectionTimeout="20000"

redirectPort="9441"

URIEncoding="GBK"/>

第三处:port对应Apache配置文件中配置的portredirectPort,注意编码

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

替换成:

<Connector port="9101" protocol="AJP/1.3" redirectPort="9441"
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">下面添加以下字段:

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
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这个类来实现。

private SpannableString convertNormalStringToSpannableString(String message , final TextView tv) {
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;
}

  首先将我们传入的message转化成SpannableString类,然后看一下传入的值是否符合我们一开始写好的正则表达式EMOTION_URL

private Pattern EMOTION_URL = Pattern.compile("\\[(\\S+?)\\]");

  如果符合的话 我们取group(0)

  附:group是针对()来说的,group0)就是指的整个串,group1指的是第一个括号里的东西,group2)指的第二个括号里的东西。

  子表达式和起始位置和结束位置的差小于8,也就是符合我们的要求。调用FaceManager中的getFaceId方法

public int getFaceId(String faceStr){
if(mFaceMap.containsKey(faceStr)){
return mFaceMap.get(faceStr);
}
return -1;
}

  找到我们用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如下:

public class AnimatedImageSpan extends DynamicDrawableSpan {

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阅读更多内容

没有评论:

发表评论