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,下 ...
随机推荐
- Moving a Subversion Repository to Another Server
Moving a subversion repository from one server to another, while still preserving all your version h ...
- latex引用多篇参考文献
1.如何使连续的参考文献能够中间用破折号连起来?比如[6,7,8,9]变成[6-9]? 方法:在文档开始前加上下面的语句命令 \usepackage[numbers,sort&compress ...
- Vijos1675 NOI2005 聪聪和可可 记忆化搜索
简单题,结果因为理解错题意懵逼了好久…… moveTo[x][y]表示聪聪在节点x,可可在节点y时,聪聪下一步应到达哪一个节点 dp[x][y]表示聪聪在节点x,可可在节点y,且轮到可可行动时,所需时 ...
- 自构BeanHandler(用BeansUtils)
class BeanHandler<T> implements ResultSetHandler<T>{ private Class<T> clazz; publi ...
- @import————————css代码内部链接另外css
在css代码里这样可以链接另外的css @import url("style.css"); @import语法结构 @import + 空格+ url(CSS文件路径地址); ...
- 一些CMS网站系统漏洞,练手用(持续更新)
仅供拿shell,提权测试用,请勿恶意破坏 XuSoft系统: 后台万能密码:'or'='or' 可直接登陆,后台地址 /manage/login.asp inurl:ReadArticlemb.a ...
- python django 自定义 装饰器
# -*-coding:utf-8-*- __author__ = "GILANG (pleasurelong@foxmail.com)" """ d ...
- readline函数分析
函数功能:提示用户输入命令,并读取命令/****************************************************************************/ /* ...
- Microsfot SQL Server 2012 日志收缩
//Microsfot SQL Server 2012 日志收缩 USE DataBaseName;GO ALTER DATABASE DataBaseNameSET RECOVERY SIMPLE; ...
- oracle积累继续
选出当天的日期的数据 select * from test_table where to_char(datetime, 'yyyy-mm-dd')=to_char(sysdate,'yyyy-mm-d ...