源码分析Dubbo服务提供者、服务消费者并发度控制机制,web程序设计课题

} finally {

if(acquireResult) { // @6

executesLimit.release();

}

}

}

代码@1:从服务提供者列表中获取参数executes的值,如果该值小于等于0,表示不启用并发度控制,直接沿着调用链进行调用。

代码@2:根据服务提供者url和服务调用方法名,获取RpcStatus。

public static RpcStatus getStatus(URL url, String methodName) {

String uri = url.toIdentityString();

ConcurrentMap<String, RpcStatus> map = METHOD_STATISTICS.get(uri);

if (map == null) {

METHOD_STATISTICS.putIfAbsent(uri, new ConcurrentHashMap<String, RpcStatus>());

map = METHOD_STATISTICS.get(uri);

}

RpcStatus status = map.get(methodName); /

if (status == null) {

map.putIfAbsent(methodName, new RpcStatus());

status = map.get(methodName);

}

return status;

}

这里是并发容器ConcurrentHashMap的经典使用,从 这里可以看出ConcurrentMap< String, ConcurrentMap< String, RpcStatus>> METHOD_STATISTICS的存储结构为 { 服务提供者URL唯一字符串:{方法名:RpcStatus} }。

代码@3:根据服务提供者配置的最大并发度,创建该服务该方法对应的信号量对象。

public Semaphore getSemaphore(int maxThreadNum) {

if(maxThreadNum <= 0) {

return null;

}

if (executesLimit == null || executesPermits != maxThreadNum) {

synchronized (this) {

if (executesLimit == null || executesPermits != maxThreadNum) {

executesLimit = new Semaphore(maxThreadNum);

executesPermits = maxThreadNum;

}

}

}

return executesLimit;

}

使用了双重检测来创建executesLimit 信号量。

代码@4:如果获取不到锁,并不会阻塞等待,而是直接抛出RpcException,服务端的策略是快速抛出异常,供服务调用方(消费者)根据集群策略进行执行,例如重试其他服务提供者。

代码@5:执行真实的服务调用。

代码@6:如果成功申请到信号量,在服务调用结束后,释放信号量。

总结:< dubbo:service executes=“”/>的含义是,针对每个服务每个方法的最大并发度。如果超过该值,则直接抛出RpcException。

2、源码分析ActiveLimitFilter

@Activate(group = Constants.CONSUMER, value = Constants.ACTIVES_KEY )

  • 过滤器作用

消费端调用服务的并发控制。

  • 使用场景

控制同一个消费端对服务端某一服务的并发调用度,通常该值应该小于< dubbo:service executes=“”/>

  • 阻断条件

非阻断,但如果超过允许的并发度会阻塞,超过超时时间后将不再调用服务,而是直接抛出超时。

源码分析ActiveLimitFilter的实现原理:

ActiveLimitFilter#invoke

public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {

URL url = invoker.getUrl();

String methodName = invocation.getMethodName();

int max = invoker.getUrl().getMethodParameter(methodName, Constants.ACTIVES_KEY, 0); // @1

RpcStatus count = RpcStatus.getStatus(invoker.getUrl(), invocation.getMethodName()); // @2

if (max > 0) {

long timeout = invoker.getUrl().getMethodParameter(invocation.getMethodName(), Constants.TIMEOUT_KEY, 0); // @3

long start = System.currentTimeMillis();

long remain = timeout;

int active = count.getActive(); // @4

if (active >= max) { // @5

synchronized (count) {

while ((active = count.getActive()) >= max) {

try {

count.wait(remain);

} catch (InterruptedException e) {

}

long elapsed = System.currentTimeMillis() - start;

remain = timeout - elapsed;

if (remain <= 0) { // @6

throw new RpcException("Waiting concurrent invoke timeout in client-side for service: "

  • invoker.getInterface().getName() + ", method: "

  • invocation.getMethodName() + ", elapsed: " + elapsed

  • ", timeout: " + timeout + ". concurrent invokes: " + active

  • ". max concurrent invoke limit: " + max);

}

}

}

}

}

try {

long begin = System.currentTimeMillis();

RpcStatus.beginCount(url, methodName); // @7

try {

Result result = invoker.invoke(invocation); // @8

RpcStatus.endCount(url, methodName, System.currentTimeMillis() - begin, true); // @9

return result;

} catch (RuntimeException t) {

RpcStatus.endCount(url, methodName, System.currentTimeMillis() - begin, false);

throw t;

}

} finally {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数同学面临毕业设计项目选题时,很多人都会感到无从下手,尤其是对于计算机专业的学生来说,选择一个合适的题目尤为重要。因为毕业设计不仅是我们在大学四年学习的一个总结,更是展示自己能力的重要机会。

因此收集整理了一份《2024年计算机毕业设计项目大全》,初衷也很简单,就是希望能够帮助提高效率,同时减轻大家的负担。
img
img
img

既有Java、Web、PHP、也有C、小程序、Python等项目供你选择,真正体系化!

由于项目比较多,这里只是将部分目录截图出来,每个节点里面都包含素材文档、项目源码、讲解视频

如果你觉得这些内容对你有帮助,可以添加VX:vip1024c (备注项目大全获取)
img

8)]
[外链图片转存中…(img-hKxNuSdI-1712584936828)]

既有Java、Web、PHP、也有C、小程序、Python等项目供你选择,真正体系化!

由于项目比较多,这里只是将部分目录截图出来,每个节点里面都包含素材文档、项目源码、讲解视频

如果你觉得这些内容对你有帮助,可以添加VX:vip1024c (备注项目大全获取)
[外链图片转存中…(img-kRXmGXTr-1712584936828)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值