博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
架构优化 - 应用,MQ Broker,业务处理分层
阅读量:6617 次
发布时间:2019-06-25

本文共 5945 字,大约阅读时间需要 19 分钟。

  hot3.png

回顾

之前的两篇文章 与  以邮件发送系统为例,演示了网站架构的优化。

第一篇文章中的架构为同步式的,即用户请求,业务处理,用户响应是在一个线程中同步处理的。当业务处理需要花太多时间的时候,用户的体验度将大大下降。当大量并发的时候,用户的业务请求又无法得到响应。

第二篇文章对之前的邮件发送系统进行了优化,使用消息队列异步处理用户的业务。这样可以减少用户的响应时间,并在高并发的时候通过消息队列,延迟处理,以减缓服务器压力,避过洪峰。但由于用户请求处理,消息队列,以及业务处理均在同一个服务器上,它只能负担小型网站,但无法在性能,伸缩性,可用性上满足大型网站的需求。

本篇文章将继续前两篇文章的道路,改进架构,以满足大型网站的需求。

架构

为了提高网站的性能,伸缩性和可用性,首先要做的就是对架构分层。将应用层或展示层和业务层,如果有数据访问层,统统分开。可以将它们放在不同的服务器上。以我们的邮件系统为例,首先需要对此分层,每层部署在单独的服务器上。

175622_H7QW_254689.png

上图的模式无法满足可用性。一旦一个server挂掉,整个网站就瘫痪了。

为了提供网站并发的能力,提高可用性和伸缩性,可以将上面的架构改造成集群方式。

181010_aL2m_254689.png

每个集群的节点可能在不同的物理机上,这样实现了高可用性,如果需要提高性能,可以继续想cluster中添加节点,这实现了伸缩性。

GlassFish Cluster,MQ cluster都不是很复杂,网上有大量的文档。然后cluster的搭建也是有多重方式的。应对不同容量的网站,cluster的搭建方式不同。越是高并发的cluster,越需要无状态的cluster。这点会在另一篇文章中详细叙述。

今天的例子,主要是针对分层,并不针对cluster。

分层实现

前提软件

  1. Glassfish4

  2. Standalone Open MQ

部署结构

最佳验证方式是使用3台物理机,其中其中两台安装glassfish,第三台安装Open MQ。应用层和业务层分别部署在两个不同的glassfish上,应用层与业务层通过第三台上的Open MQ进行消息传递。

如果没有3台物理机,也可以将它们装在一个物理机上。复制两份glassfish,一个安装应用层,一个安装业务层,同时启动,也可以模拟分布式。

安装配置Open MQ

  1. 到网站 下载最新版的MQ。

  2. 将下载的MQ压缩包解压到例如D:\sts\MessageQueue5.0。假设此目录为MQ_HOME.

  3. 打开文件MQ_HOME/etc/mq/imqenv.conf,加入

    REM 如果消息的持久化需要数据库支持,则需要额外的数据库连接,把MQ需要的包放到下面。为了简单,本文使用文件持久化。REM set IMQ_DEFAULT_EXT_JARS=c:\Program Files\Sun\JavaES5\hadb\4.4.3-5\lib\hadbjdbc4.jar;c:\Program Files\Sun\JavaDB\lib\derby.jarset IMQ_DEFAULT_JAVAHOME=D:\sts\jdk1.7.0_10set IMQ_DEFAULT_VARHOME=D:\sts\MessageQueue5.0\var
  4. 启动MQ,运行命令

    MQ_HOME/mq/bin/imqbrokerd.exe -name mybroker -port 7677

    查看log,发现Broker "mybroker@pcname:7677" ready.

  5. 添加MQ用户,运行命令

    MQ_HOME/mq/bin/imqusermgr.exe add -i mybroker -u xpbug -p xpbug
  6. 列出用户:

    MQ_HOME/mq/bin/imqusermgr.exe list -i mybroker -u xpbug

配置Glassfish的JMS服务

两个Glassfish的配置方法相同。首先打开glassfish的控制界面: 

如果Glassfish配置了cluster,JMS服务需要在cluster下创建,如果没有配置cluster,则需要在Server-config目录下配置JMS服务。另外一种方式就是使用JCA架构,配置Connector Resource,这种方式可以通过此文了解 

  1. 展开Configurations->Default-config->Java Mail Service,点击JMS hosts,删除Glassfish自带的defalt jms host。然后点击new按钮,创建自己的JMS host。

    001810_HXgM_254689.png

  2. 然后在左边的navigation中,点击Java Mail Service,选择remote jms host。

    002046_6HhU_254689.png

  3. 保存以后,我们的glassfish开始使用remote standalone OpemMQ了。

  4. 接下来,在Resources下面分别创建自己的ConnectionsFactory JNDI和JMS Destination JNDI

    002315_ZXrR_254689.png

  5. 保存以后,Glassfish的配置就完成了。

在业务层服务器上配置Java Mail Session

请在上一篇文章中 找到Gmail的配置方法。

开发应用层

创建一个Web项目,取名叫sample.

在welcome页面中,加入代码:

index.html

            TODO supply a title        
        
                
            Email:
            
                        

创建NotifyServlet:

package com.mycompany;import java.io.IOException;import java.io.PrintWriter;import javax.annotation.Resource;import javax.jms.ConnectionFactory;import javax.jms.JMSContext;import javax.jms.Queue;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * * @author none2 */@WebServlet(name = "NotifyServlet", urlPatterns = {"/NotifyServlet"})public class NotifyServlet extends HttpServlet {    @Resource(lookup = "java:comp/MyJMSConnectionFactory")    private ConnectionFactory connectionFactory;        @Resource(lookup = "jms/myQueue")    private Queue queue;        @Override    protected void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        String email = request.getParameter("email");        try (JMSContext context = connectionFactory.createContext();) {            context.createProducer().send(queue, email);        }        response.setContentType("text/html;charset=UTF-8");        try (PrintWriter out = response.getWriter()) {            /* TODO output your page here. You may use following sample code. */            out.println("");            out.println("");            out.println("");            out.println("Servlet NotifyServlet");                        out.println("");            out.println("");            out.println("

You have send a notification to " + email + "

");            out.println("");            out.println("");        }    }}

然后打包web项目,并部署到glassfish1上。

开发业务层

创建一个EJB module project。在项目中,创建一个Message Driven Bean。

package com.mycompany;import java.util.logging.Level;import java.util.logging.Logger;import javax.ejb.ActivationConfigProperty;import javax.ejb.MessageDriven;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.MessageListener;import javax.mail.Address;import javax.mail.MessagingException;import javax.mail.Session;import javax.mail.Transport;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeMessage;import javax.naming.Context;import javax.naming.InitialContext;import javax.naming.NamingException;/** * * @author none2 */@MessageDriven(activationConfig = {    @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/myQueue"),    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")})public class EmailMessageBean implements MessageListener {    private final Session mySession;        public EmailMessageBean() throws NamingException {        Context initCtx = new InitialContext();        mySession = (Session) initCtx.lookup("mail/mySession");    }        @Override    public void onMessage(Message message) {            try {            String address = message.getBody(String.class);            javax.mail.Message mail = new MimeMessage(mySession);            mail.setFrom(new InternetAddress("joey.zhangpeng@gmail.com"));            Address toAddress = new InternetAddress(address);            mail.addRecipient(javax.mail.Message.RecipientType.TO, toAddress);            mail.setSubject("Hello");            mail.setText("A notification.");            Transport.send(mail);        } catch (MessagingException | JMSException ex) {            Logger.getLogger(EmailMessageBean.class.getName()).log(Level.SEVERE, null, ex);        }    }    }

然后将EJB打包,并部署到glassfish2上。

接下来,测试一下email系统是否工作吧。

转载于:https://my.oschina.net/xpbug/blog/265017

你可能感兴趣的文章
AES加密算法动画演示
查看>>
Linux网络性能评估工具iperf
查看>>
hdfs-site.xml配置
查看>>
11g RAC OCR,VOTING DISK存储全部损坏,利用自动备份,恢复OCR,VOTING DISK到新存储。...
查看>>
heartbeat+Haproxy多VIP负载均衡高可用
查看>>
SQL Server 作业同步
查看>>
uC/OS-II源码分析(四)
查看>>
JavaScript字符集编码与解码
查看>>
mysql的主从复制和读写分离
查看>>
将Active Directory组成员复制到新组
查看>>
中国信息通信研究院发布《网络安全产业白皮书(2017)》
查看>>
关于对centos bash_profile的初步认识
查看>>
Python学习(1)--变量与表达式
查看>>
Flutter环境搭建
查看>>
zabbix 获取Windows Server 信息
查看>>
菜鸟学Linux 第041篇笔记 常见系统故障排除
查看>>
postfix服务
查看>>
测试电脑的存储方式(大端or小端)
查看>>
puppet自动化运维工具安装配置
查看>>
centos7iptables和rc.local问题
查看>>