千万用户级别应用系统背后的SOA组件化容器
背景
在《我们的应用系统是如何支撑千万级别用户的》随笔中已经从“宏观”角度去介绍了整个应用系统的布局。组件化是整个系统由头到尾都始终坚持的一个设计原则,其中“SOA组件化容器”也是我们应用系统比较特别的一点。好东西肯定要分享,当然,这个好还只停留在自恋当中。
主题
上图为整个SOA容器(即WEB容器)的透析图。其中各个(黄色)组件的执行流程就是整条业务线程的执行流程。例如在我们应用系统中主要包括会话组件、安全拦截组件、业务验证组件、业务解析组件、业务服务组件、业务响应组件、日志组件等。也就是这些组件组成了整个业务线程的生命周期。接下来对SOA容器的各个组成部分进行一一介绍。
SOA组件配置文件
配置文件就是组件执行引擎的依赖,有点类似于Spring配置文件的概念,下面是配置文件的一个例子:
<?xml version="1.0" encoding="UTF-8"?>
<soabean id=”session” class=”com.soa.session” order=”1”/>
<soabean id=”security” class=”com.soa. security” order=”2”/>
<soabean id=”validate” class=”com.soa.validate” order=”3”/>
<soabean id=”analysis” class=”com.soa.analysis” order=”4”/>
<soabean id=”service” class=”com.soa.service” order=”5”/>
<soabean id=”response” class=”com.soa.response” order=”6”/>
<soabean id=”logger” class=”com.soa.logger” order=”7”/>
其中soabean为SOA容器组件,id为组件的唯一标识,class为组件的类路径,order为组件的执行顺序。
SOA组件执行引擎
执行引擎就是整个SOA组件容器的发动机,容器初始化时需要加载SOA组件配置文件信息并通过反射生成各组件实例根据序号(order)依序存放在SOA组件单例队列容器里。当业务请求到达SOA容器时,执行引擎循环执行单例队列容器里面的组件。
/*伪代码*/
Loop singleSOABeanList: //循环组件单例队列容器
SOABean.handle(); //组件执行
SOA组件单例队列容器
这是一个存放着SOA组件实例的单例队列容器,队列的顺序依赖于配置文件的order值,按队列容器按order值升序排序,order值越小的组件越优先执行。
ThreadLoal(线程本地变量)
这是整个线程生命周期的本地变量,主要存储的是会话信息,而这个会话信息就是各组件解耦的关键所在,贯穿了所有组件的执行。会话信息主要包含着以下字段:
Class Session{
serssionId //会话标识
seviceName //请求服务标识,如SOA_001_001,可自定义业务规则
retCode //业务响应标识
retDesc //业务响应描述
isGone=true //线程主流程执行信号(true/false)
soaLogger //SOA容器组件日志跟踪器
reqJson //请求参数报文
respJson //响应参数报文
HTTPRequest实例
HTTPRespone实例
Userinfo //用户信息
……
}
此会话跟HTTP会话的作用是一样的,主要是维护用户不同请求的关联关系,同时还是各组件的解耦的关键所在。
SOA组件
上图中的黄色组件为各SOA容器的业务组件,业务组件需要实现SOA组件接口。
public interface SOAInterface {
public void handle();
}
组件是一个独立体,必须管理好自己所以异常信息,可通过会话实体记录和跟踪会话的运行情况。组件又分为主流程组件和辅助组件,主流程组件是通过会话的线程主流程执行信号(isGone)来跟踪主业务流程的执行情况,如果某主业务流程组件发生异常或业务失败,则通过session.setIsGone = false告诉后续的主流程组件不需要执行了:
/*主流程组件伪代码*/
Class SubGroup implement SOAInterface(){
try{
If(session.isGone){
operations
…
If(operation false){
session.setIsGone = false;
}
}
}catch(Exception e){
session.setExceptionLog;
session.setIsGone = false;
}
}
在我们应用中,主流程组件有会话组件、请求解析组件、业务处理组件、请求业务响应组件等。而辅助组件有黑名单拦截组件,日志组件等。辅助组件的异常不会导致整条业务线程的奔溃,遇到异常,不会对主线程的运行标识(isGone)进行干预,以免影响整条主业务线程的正常服务。例如黑名单拦截,如果就因为黑名单组件异常失败,而停止系统所有业务对外提供服务,那有点说不过去。其实说白了,还是根据自己业务而定。对于一些比较敏感的系统组件,可以通过实时异常监控组件去跟踪来弥补日志异常信息监控缓慢的缺点。例如可以利用“发布订阅系统”:
/*会话记录组件异常信息伪代码*/
session.setExceptionLog(){
ExceptionLog;
PubSubMonitor.publish(exceptioninfo); //通过发布订阅监控组件实时监控
}
总结
不难理解,各个组件就是线程栈的组成部分。SOA组件化容器把整个业务请求流程的各个组成部分都封装成组件化形式执行,例如会话解析、请求参数解析、业务逻辑处理、请求业务响应、日志记录等业务主要流程。有利于系统日后的扩展性和维护性。这个SOA容器其实有点类似于企业服务总线(ESB)的概念,也同样支持类似Spring的AOP功能,毕竟在一条垂直的业务线程上,可通过组件配置文件在随意一个横切面插入其他操作组件。无论SOA容器组件还是服务层(SOA容器业务逻辑处理组件)的业务服务组件,都是通过反射实现生产单例使用,也有点类似于Spring的IOC概念。在这里我主要还是提供想法和思路,只有思路是通用的,还是建议思路+具体业务的实现才能发挥系统的最大性能。DIY过程最好不要脱离组件化和简单化的设计原则,当然,定义=限制,不同人都有不同的可能,欢迎评论交流。
千万用户级别应用系统背后的SOA组件化容器的更多相关文章
- 【PHP自定义显示系统级别的致命错误和用户级别的错误】
使用方法set_error_handler可以自定义用户级别的错误和系统级别的错误信息显示和处理 用户级别的错误使用trigger_error方法产生一个用户级别的错误信息 代码示例: 系统级别的错误 ...
- Linux 管理环境变量的文件分为系统级和用户级别
Linux 管理环境变量的文件分为系统级和用户级别 管理环境变量的文件也分为系统级和用户级别: 1.系统级:/etc/profile:该文件是用户登录时,操作系统定制用户环境时使用的第一个文件,应用于 ...
- 如何打造千万级Feed流系统
from:https://www.cnblogs.com/taozi32/p/9711413.html 在互联网领域,尤其现在的移动互联网时代,Feed流产品是非常常见的,比如我们每天都会用到的朋友圈 ...
- 【Linux_Fedora_系统管理系列】_1_用户登录和系统初始配置
发现一个问题,在FC14 的Firefox浏览器中,编辑和排版好的博文,在windows下用chrome或者猎豹浏览器打开后,排版就变得阅读 不是很容易里,而且经常不经意的断行.不知道园子的管理人员时 ...
- SHA-1退休:数千万用户通向加密网站之路被阻
Facebook和Cloudflare警告道:上千万用户将无法访问只使用SHA-2签名证书的HTTPS网站.2016年-2017年是SHA-1算法的缓冲期.2017年开始CA机构将不能颁发含有sh ...
- 深喉起底APP线下预装市场,如何一夜间拥有千万用户
注:预装对于中国的移动互联网创业者有多重要?i黑马知道这样一个内幕,某商务告诉我他们公司的前2000万用户就是靠预装打下来的,总部在北京,直接派驻商务长期扎根在深圳搞定手机厂商.而这家公司初期发展得益 ...
- 网络设备 密码、用户级别 AAA授权 的管理
一.进入 特权模式 密码 设置访问网络设备特权模式口令 cisco>enable cisco#config terminal cisco(config)#enable password 密码 e ...
- 用户视角 vs 系统视角 看性能
如何评价性能的优劣: 用户视角 vs. 系统视角 对于最终用户(End-User)来说,评价系统的性能好坏只有一个字——“快”.最终用户并不需要关心系统当前的状态——即使系统这时正在处理着成千上万的请 ...
- Radius 远程用户拨号认证系统
RADIUS 锁定 本词条由“科普中国”百科科学词条编写与应用工作项目 审核 . RADIUS:Remote Authentication Dial In User Service,远程用户拨号认证系 ...
随机推荐
- extjs学习(关于grid)
1.想要调整某一列在表格中的顺序,可以使用mapping(索引是从0开始的) var store = new Ext.data.ArrayStore({ data:data, fields:[ {na ...
- js数组方法push pop shift unshift的返回值
push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度. pop() 方法用于删除并返回数组的最后一个元素. unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度. s ...
- c# Exception 异常信息归整
private string ErrorMessage(Exception exception) { StringBuilder stringBuilder = new StringBuilder() ...
- 第三章 Docker 入门
第三章 docker 入门 3.1 确保docker已经就绪 首先查看docker程序是否存在,功能是否正常 [#3#cloudsoar@cloudsoar-virtual-machine ~]$su ...
- android nio
Android开发进阶之NIO非阻塞包(二) 有关Android NIO我们主要分为三大类,ByteBuffer.FileChannel和SocketChannel.由于篇幅原因今天Android12 ...
- JAVA编程心得-Eclipse/MyEclipse 中文乱码解决办法
将别人的项目或JAVA文件导入到自己的Eclipse中时,常常会出现JAVA文件的中文注释变成乱码的情况,主要原因就是别人的IDE编码格式和自己的Eclipse编码格式不同.总结网上的建议和自己的体会 ...
- C# System.Timers.Timer的一些小问题?
比如设置间隔时间是 1000msSystem.Timers.Timer mytimer = new System.Timers.Timer(1000);问题若响应函数执行的时间超过了 1000 ms, ...
- hdoj 1002 A+B(2)
Problem Description I have a very simple problem for you. Given two integers A and B, your job is to ...
- [转]SQL Server字符串处理函数大全
select语句中只能使用sql函数对字段进行操作(链接sql server), select 字段1 from 表1 where 字段1.IndexOf("云")=1;这条语句不 ...
- 使用nginx为ArcGIS Server做反向代理
1.下载nginx软件:官网地址http://nginx.org/ 2.修改conf文件夹下nginx.conf配置信息, 配置文件中以下内容: server { listen 80; s ...