设为首页 收藏本站
查看: 641|回复: 0

[经验分享] 使用Apache+Tomcat构建应用服务器集群

[复制链接]

尚未签到

发表于 2017-1-11 06:24:49 | 显示全部楼层 |阅读模式
  1.安装Apache HTTP server:http://httpd.apache.org/
  2.安装2-3个(或更多)Tomcathttp://tomcat.apache.org/,安装zip版,因为安装多个Windows Service Installer版会出现错误(可以安装一个Installer版,其他两个用zip版)。
  3.配置3个Tomcat,使得3个Tomcat在一台机器上可以同时运行:
  修改三个Tomcat安装目录下的bin/startup.bat,将其中的CATALINA_HOME环境变量修改成互不相同的名字,比如CATALINA_HOME1,CATALINA_HOME2,CATALINA_HOME3。
  4.配置集群
  1) 修改Apache安装目录下的conf/httpd.conf文件,在文件末尾加入如下几行ProxyRequests Off <proxy balancer://cluster> BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=jvm1BalancerMember ajp://127.0.0.1:9009 loadfactor=1 route=jvm2BalancerMember ajp://127.0.0.1:9099 loadfactor=1 route=jvm3</proxy>8009,9009,9099分别是三个Apache用来于Tomcat连接的端口oadfactor是指每一个tomcat的负载系数。
  2) 修改Tomcat下的conf/server.xml
  a.将所有3个Tomcat的server.xml中的
  <Engine name="Catalina" defaultHost="localhost">
  修改为<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">,3个tomcat的jvmRoute分别为jvm1,jvm2,jvm3
  b.修改所有3个server.xml中的<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />,将8009端口改为与上面Apache中配置的三个端口一致(这点很重要!),与上面配置的jvm1,jvm2也要一致。也就是说,配置为jvm1的,这里端口改为8009,配置为jvm2的tomcat,这里端口给为9009,jvm3的为9099。
  c.修改server.xml中的所有其他端口,使得3个tomcat没有重复的端口,包括:<Server port="8005",<Connector port="8080",redirectPort="8443" 这三个,三个tomcat的这三个端口都要不一样,其中每个tomcat中有两个redirectPort,同一个tomcat中的redirectPort一样,不同tomcat中的redirectPort不一样。
  4.现在,集群就应该已经正确的构建完毕,访问Apache(localhost,端口为80)时,Apache就会将请求转发给这3个tomcat中的一个,可以自己写一个JSP或者servlet试试,注意,三个tomcat中的webapp下面都需要有一份JSP/servlet。
  5.写一个实验程序(servlet),发布到3个tomcat上,写一个客户端程序,多线程并发访问Apache,观察三个tomcat的负载均衡情况(可以调节一下loadfactor再观察),并绘制在线程越来越多的情况下,响应时间曲线。
  由于规模较小的计算,响应时间非常快,可以忽略。所以选择一个计算量较大的运算:判断一个数是否为素数,Sevlet代码如下:package com.hw;import java.io.IOException;import java.math.BigDecimal;import java.math.BigInteger;import java.math.MathContext;import java.math.RoundingMode;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/*** Servlet implementation class JudgePrimeServlet*/public class JudgePrimeServlet extends HttpServlet {private static final long serialVersionUID = 1L;private static final String TRUE_JSON = "{success:true}";private static final String FALSE_JSON = "{success:false}";public JudgePrimeServlet() {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String numStr =  request.getParameter("number");boolean ans;if(numStr.length() < 10)ans = isPrime(Long.parseLong(numStr));elseans = isPrime(new BigInteger(numStr));System.out.println(numStr + " : " + ans);response.getWriter().write(ans ? TRUE_JSON : FALSE_JSON);response.getWriter().flush();response.getWriter().close();}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}public static boolean isPrime(long n){if(n % 2 == 0){if(n == 2)return true;return false;}long up = (long)Math.sqrt((double)n);for(int i = 3; i <= up; i += 2)if(n % i == 0)return false;return true;}public static boolean isPrime(BigInteger n){if(n.mod(BigInteger.valueOf(2)).equals(BigInteger.ZERO)){if(n.equals(BigInteger.valueOf(2)))return true;return false;}MathContext mc = new MathContext(n.toString().length(), RoundingMode.HALF_DOWN);BigInteger up = new BigDecimal(Math.sqrt(n.doubleValue()) ,mc).toBigInteger();for(BigInteger i = BigInteger.valueOf(3); i.compareTo(up) <= 0; i = i.add(BigInteger.valueOf(2)))if(n.mod(i).equals(BigInteger.ZERO))return false;return true;}},客户端的线程代码如下:public class ClientTestThread extends Thread{public static final long[] primeArr = new long[] { 2055437, 2057317, 5298991, 5300467, 5352869, 5377679, 6220229,7155887, 8491247, 8885837, 9999929, 9999931, 9999943, 9999971, 9999973, 9999991, 11547391, 12531809,13192643, 15766453, 16854379, 26459779, 26456789, 26453803, 29999791, 1000003871, 1015490783, 1800000011,1800000019, 1800000047, 1800000049, 1800000053, 1800000061, 1800000109, 1800000113, 1800001523, 1978012607,1978012609, 1978012633, 1978012669, 1978012703, 1978012709, 1978012739, 1978012741, 1978012759, 1978012763,2008693679, 2008693681, 2008693727, 2008693741, 2008693759, 2095462079, 2095462099, 2095462151, 2095462163,2095462207, 2099999999 };private static Long timer = 0L;@Overridepublic void run(){URL url;HttpURLConnection conn;long millisec = GregorianCalendar.getInstance().getTimeInMillis();try{url = new URL("http://localhost/ClusterExp/JudgePrimeServlet?number=" + 2099999999);conn = (HttpURLConnection) url.openConnection();Scanner scan = new Scanner(conn.getInputStream());if(scan.hasNext())scan.nextLine();scan.close();ClientTestThread.addToTimer((GregorianCalendar.getInstance().getTimeInMillis() - millisec));}catch (MalformedURLException e){e.printStackTrace();}catch (IOException e){e.printStackTrace();}}public static void addToTimer(long time){synchronized (timer){timer += time;}}public static void clearTimer(){synchronized (timer){timer = 0L;}}public static Long getTimer(){return timer;}},客户端界面以及生成多线程、绘制响应时间曲线代码如下(使用SWT,如果要运行,需要使用eclipse.org的SWT包):package com.hw.client;import org.eclipse.swt.SWT;public class TestClient{protected Shell shell;private Text lowField;private Text highField;private Group lineGroup;private static final int unit = 10;private static final int off = 10;private static final int width = 800;private static final int height = 600;/*** Launch the application.* * @param args*/public static void main(String[] args){try{TestClient window = new TestClient();window.open();}catch (Exception e){e.printStackTrace();}}/*** Open the window.*/public void open(){Display display = Display.getDefault();createContents();shell.open();shell.layout();while (!shell.isDisposed()){if (!display.readAndDispatch()){display.sleep();}}}/*** Create contents of the window.*/protected void createContents(){shell = new Shell();shell.setSize(1024, 768);shell.setText("/u8D1F/u8F7D/u5E73/u8861/u6D4B/u8BD5/u5BA2/u6237/u7AEF");shell.setLayout(null);Composite composite = new Composite(shell, SWT.NONE);composite.setBounds(10, 10, 655, 97);Group group = new Group(composite, SWT.NONE);group.setBounds(10, 23, 422, 64);group.setText("/u6D4B/u8BD5/u7684/u7EBF/u7A0B/u6570/u91CF/u533A/u95F4");group.setLayout(null);Label label = new Label(group, SWT.NONE);label.setBounds(10, 27, 60, 12);label.setText("/u4E0B/u9650");lowField = new Text(group, SWT.BORDER);lowField.setBounds(76, 24, 106, 18);Label label_1 = new Label(group, SWT.NONE);label_1.setBounds(198, 27, 60, 12);label_1.setText("/u4E0A/u9650");highField = new Text(group, SWT.BORDER);highField.setBounds(265, 24, 106, 18);Button button = new Button(composite, SWT.NONE);button.addSelectionListener(new SelectionAdapter() {@Overridepublic void widgetSelected(SelectionEvent arg0) {GC gc = new GC(lineGroup);gc.setForeground(new Color(Display.getCurrent(), 255, 0, 0));gc.drawLine(off, height - off, width + off, height - off);gc.drawLine(off, height - off, off, off);for(int i = 1; i < width / unit; ++ i){if( i % 5 == 0)gc.drawString(String.valueOf(i), i * unit + off - 2, height - off + 3);}gc.drawString("线程数", width + off, height - off - 10);gc.setBackground(new Color(Display.getCurrent(), 255, 0, 0));for(int i = 1; i < width / unit; ++ i){gc.fillRectangle(i * unit + off, height - off - 3, 2, 3);}for(int i = 1; i < height / unit; ++ i){gc.fillRectangle(off, height - off - i * unit, 3, 2);}int low = Integer.parseInt(lowField.getText());int high = Integer.parseInt(highField.getText());int lastX = off, lastY = height - off;int x, y;for (int i = low; i <= high; ++i){Thread[] multiThread = new ClientTestThread;for (Thread t : multiThread){t = new ClientTestThread();t.start();}boolean allFinished = false;while (!allFinished){allFinished = true;for (Thread t : multiThread){if (t != null && t.isAlive()){allFinished = false;Thread.yield();break;}}}x = i * unit + off;y = height - off - ClientTestThread.getTimer().intValue() / i / 3;if(y < 0)y = 0;gc.drawLine(lastX, lastY, x, y);System.out.println(x  + "," + y);lastX = x;lastY =y;//gc.fillOval(i, 600 - ClientTestThread.getTimer().intValue(), 3,3);// gc.drawPoint(i, ClientTestThread.getTimer().intValue());ClientTestThread.clearTimer();}}});button.addMouseListener(new MouseAdapter(){@Overridepublic void mouseDown(MouseEvent arg0){}});button.setBounds(476, 53, 72, 22);button.setText("/u6D4B/u8BD5");lineGroup = new Group(shell, SWT.NONE);lineGroup.setText("/u8D1F/u8F7D/u66F2/u7EBF");lineGroup.setBounds(10, 113, 996, 618);}},运行后,三个tomcat的控制台都会输出结果,说明请求被分发给三个tomcat,运行1-75个线程的响应时间曲线如下: DSC0000.png

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-326610-1-1.html 上篇帖子: Apache MINA 1.x 中的ByteBuffer对象使用的问题 下篇帖子: Apache Rewrite实现URL的301跳转和域名跳转
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表