motan源码分析十一:部分特性
本章将描述motan部分的特性并对源码进行分析。
1.requestid的维护,使用了当前时间左移20位,再和一个自增变量组合
public class RequestIdGenerator {
protected static final AtomicLong offset = new AtomicLong();
protected static final int BITS = ;
protected static final long MAX_COUNT_PER_MILLIS = << BITS;
/**
* 获取 requestId
*
* @return
*/
public static long getRequestId() {
long currentTime = System.currentTimeMillis();
long count = offset.incrementAndGet();
while(count >= MAX_COUNT_PER_MILLIS){
synchronized (RequestIdGenerator.class){
if(offset.get() >= MAX_COUNT_PER_MILLIS){
offset.set();
}
}
count = offset.incrementAndGet();
}
return (currentTime << BITS) + count;
}
public static long getRequestIdFromClient() {
// TODO 上下文 requestid
return ;
}
}
2.限流,motan支持简单的限流,是利用filter来实现的
@SpiMeta(name = "active")
@Activation(sequence = 1)
public class ActiveLimitFilter implements Filter { @Override
public Response filter(Caller<?> caller, Request request) {
int maxAcvitivyCount = caller.getUrl().getIntParameter(URLParamType.actives.getName(), URLParamType.actives.getIntValue());
if (maxAcvitivyCount > 0) {
int activeCount = RpcStats.getServiceStat(caller.getUrl()).getActiveCount();
if (activeCount >= maxAcvitivyCount) {
throw new MotanServiceException(String.format("Request(%s) active count exceed the limit (%s), referer:%s", request,
maxAcvitivyCount, caller.getUrl()), MotanErrorMsgConstant.SERVICE_REJECT);
}
} long startTime = System.currentTimeMillis();
RpcStats.beforeCall(caller.getUrl(), request);
try {
Response rs = caller.call(request);
RpcStats.afterCall(caller.getUrl(), request, true, System.currentTimeMillis() - startTime);
return rs;
} catch (RuntimeException re) {
RpcStats.afterCall(caller.getUrl(), request, false, System.currentTimeMillis() - startTime);
throw re;
} } }
3.对于连续失败的client进行不可用操作
void incrErrorCount() {
long count = errorCount.incrementAndGet();
// 如果节点是可用状态,同时当前连续失败的次数超过限制maxClientConnection次,那么把该节点标示为不可用
if (count >= maxClientConnection && state.isAliveState()) {
synchronized (this) {
count = errorCount.longValue();
if (count >= maxClientConnection && state.isAliveState()) {
LoggerUtil.error("NettyClient unavailable Error: url=" + url.getIdentity() + " "
+ url.getServerPortStr());
state = ChannelState.UNALIVE;
}
}
}
}
void resetErrorCount() {
errorCount.set();
if (state.isAliveState()) {
return;
}
synchronized (this) {
if (state.isAliveState()) {
return;
}
// 如果节点是unalive才进行设置,而如果是 close 或者 uninit,那么直接忽略
if (state.isUnAliveState()) {
long count = errorCount.longValue();
// 过程中有其他并发更新errorCount的,因此这里需要进行一次判断
if (count < maxClientConnection) {
state = ChannelState.ALIVE;
LoggerUtil.info("NettyClient recover available: url=" + url.getIdentity() + " "
+ url.getServerPortStr());
}
}
}
}
4.支持多注册中心,因此cluster的refer集合是所有注册中心包含服务器的集合,如果同一个服务器在不同的注册中心注册,则cluster中当作两个服务器
5.服务端的采用boss线程池+工作线程池+业务线程池的处理方式
private final static ChannelFactory channelFactory = new NioServerSocketChannelFactory(//boss线程池和工作线程池,主要负责接收消息
Executors.newCachedThreadPool(new DefaultThreadFactory("nettyServerBoss", true)),
Executors.newCachedThreadPool(new DefaultThreadFactory("nettyServerWorker", true))); private StandardThreadExecutor standardThreadExecutor = null;//业务线程池,负责具体的业务处理 standardThreadExecutor = (standardThreadExecutor != null && !standardThreadExecutor.isShutdown()) ? standardThreadExecutor
: new StandardThreadExecutor(minWorkerThread, maxWorkerThread, workerQueueSize,
new DefaultThreadFactory("NettyServer-" + url.getServerPortStr(), true));
standardThreadExecutor.prestartAllCoreThreads(); final NettyChannelHandler handler = new NettyChannelHandler(NettyServer.this, messageHandler,
standardThreadExecutor);//handler使用业务线程池今天处理具体的业务
motan源码分析十一:部分特性的更多相关文章
- motan源码分析六:客户端与服务器的通信层分析
本章将分析motan的序列化和底层通信相关部分的代码. 1.在上一章中,有一个getrefers的操作,来获取所有服务器的引用,每个服务器的引用都是由DefaultRpcReferer来创建的 pub ...
- [Abp 源码分析]十一、权限验证
0.简介 Abp 本身集成了一套权限验证体系,通过 ASP.NET Core 的过滤器与 Castle 的拦截器进行拦截请求,并进行权限验证.在 Abp 框架内部,权限分为两块,一个是功能(Featu ...
- ABP源码分析十一:Timing
Timing这个简单实用的功能主要用于以统一的方式表示时间.因为ABP中有大量的module,还支持自定义module,所以将时间统一表示为local时间(默认)或utc时间是必要的. IClockP ...
- MyBatis框架的使用及源码分析(十一) StatementHandler
我们回忆一下<MyBatis框架的使用及源码分析(十) CacheExecutor,SimpleExecutor,BatchExecutor ,ReuseExecutor> , 这4个Ex ...
- jQuery 源码分析(十一) 队列模块 Queue详解
队列是常用的数据结构之一,只允许在表的前端(队头)进行删除操作(出队),在表的后端(队尾)进行插入操作(入队).特点是先进先出,最先插入的元素最先被删除. 在jQuery内部,队列模块为动画模块提供基 ...
- Vue.js 源码分析(十一) 基础篇 过滤器 filters属性详解
Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化.过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持).过滤器应该被添加在 JavaScrip ...
- motan源码分析一:服务发布及注册
motan是新浪微博开源的服务治理框架,具体介绍请看:http://tech.sina.com.cn/i/2016-05-10/doc-ifxryhhh1869879.shtml. 本系列的文章将分析 ...
- motan源码分析十:流量切换
motan提供了流量切换的功能,可以实现把一个group的流量切换到另一个group(一个或多个服务都可以).大家可以使用tomcat部署motan的管理工具,并设置几个组,例如可以参考demo代码: ...
- motan源码分析八:涉及到底层的客户端调用
之前我们分析了客户端调用服务端的源码,但是没有涉及到通讯层和序列化层,本文将之前讲过的内容做一次串联. 1.上层通过动态代理调用refer的call,每个refer又对应一个nettyclient,下 ...
随机推荐
- 第17章课后题(高级Perl技巧)
17.1 写一个程序,从文件中读取一组字符串(每行一个),然后让用户键入模式以便进行字符串匹配. 对于每个模式,程序应该说明文件里共有多少字符串匹配成功,分别是哪些字符串. 对于所键入的每个新模式,不 ...
- 从SQL2008R2导入数据到SQL2005
从SQL2008R2导入数据到SQL2005,数据很大,数据文件大概有120G. 尝试过直接离线附加,失败 尝试过备份还原,失败 最后找到了 1.先执行 exec sp_msforeachtable ...
- CSS让图片垂直居中的几种技巧 三种方法介绍
在网页设计过程中,有时候会希望图片垂直居中的情况.而且,需要垂直居中的图片的高度也不确定,这就会给页面的布局带来一定的挑战.下面总结了一下,曾经使用过的几种方法来使图片垂直居中,除了第一种方法只限于标 ...
- how to use a xml_id in field domain
"[('parent_id','child_of', %(other_module.xml_id)d)]"
- Library:python-memcached on Windows
1 install memcached 1.4.4 Windows 32-bit 2 cd into the base file and type memcached.exe -d install ...
- android开发学习笔记:圆角的Button
转自:http://www.cnblogs.com/gzggyy/archive/2013/05/17/3083218.html 在res目录下的drawable-mdpi建立xml文件shape.x ...
- NSNumber
integerfloatc 在Objective-c中有int的数据类型,那为什么还要使用数字对象NSNumber?这是因为很多类(如NSArray)都要求使用对象,而int不是对象.NSNumber ...
- 转:Google技术开发指南:给大学生自学的建议
原文来自于:http://blog.jobbole.com/80621/ 技术开发指南 想要成为成功的软件工程师,必须拥有坚实的计算机科学的基础.本指南针对大学生,给出一条自学途径,让学生以科班和非科 ...
- 【Unity探究】物理碰撞实验
这几天为了准备面试,所以决定对平时学习中的盲点扫盲一下,首先想到的就是物理碰撞.以前没有好好研究过,一直模糊不清,到底什么条件下才可以产生物理碰撞呢?只要其中一个有Rigidbody就可以了吗?所以进 ...
- HTML/W3C-WHATWG-Differences
Differences between the W3C HTML 5.1 specification and the WHATWG LS The W3C HTML 5.1 specification: ...