一. 拉取源码

到Dubbo官网 https://github.com/apache/incubator-dubbo/tree/2.5.x 下载源码,解压。

二. 导入IDEA

选择解压后的源码目录,一路点击next

三. 实现LoadBalance接口

在loadbalance包中,创建一个class,并实现LoadBalance接口。  如下:创建SameSessionIdLoadBalance类实现LoadBalance接口

/**
* 保存sessionId和服务地址的映射关系
* invoker.getUrl().getAddress()可以获取到该invoker的服务地址信息
* sessinoId存在,那么就返回sessionId所在的invoker
* sessionId不存在,那么就轮训的找一个invoker返回
*/
public class SameSessionIdLoadBalance implements LoadBalance { private final static Logger logger = LoggerFactory.getLogger(SameSessionIdLoadBalance.class); private Map<String,String> sessionIdAddress = new ConcurrentHashMap<String,String>(256); private AtomicInteger index = new AtomicInteger(0); @Override
public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {
Invoker result = null;
     //约定方法的第一个参数就是sessionId
String sessionId = (String) invocation.getArguments()[0];
if(!sessionIdAddress.containsKey(sessionId)){
result = invokers.get(index.getAndIncrement()%invokers.size());
sessionIdAddress.put(sessionId,result.getUrl().getAddress());
}else{
String destAddress = sessionIdAddress.get(sessionId);
for (Invoker<T> invoker : invokers) {
if(invoker.getUrl().getAddress().equals(destAddress)){
result = invoker;
}
}
}
logger.info("sesisonId: " + sessionId + " ,method: " + invocation.getMethodName() + " ,select " + result.getUrl().getAddress() + " broker");
return result;
}
}

四. 添加配置信息

添加的samesessionloadbalance就是该负载均衡的名字。

五. 构建安装源码

打开终端控制台执行mvn clean install -Dmaven.test.skip

最后会在maven的本地仓库中生成jar包

可以通过360解压缩查看jar包中的class文件,看看我们的代码是否编译进去了。

六. 测试代码

公共接口

public interface DemoService {
String saySomething(String msg);
}

provider实现该接口

public class DemoServiceImpl implements DemoService {
public String saySomething(String msg) {
     //每次启动 把20880改成相应的端口 方便观察结果。
return "this is 20880 " + msg;
}
}

Provider启动

public class Provider {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:provider.xml");
ctx.start();
System.in.read();
}
}

provider.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="hello-world-app" /> <!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://10.130.41.36:2181"/> <!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" /> <!-- 声明需要暴露的服务接口 -->
<!--samesessionloadbalance-->
<dubbo:service interface="com.xxx.testdubbo.DemoService" ref="demoService" loadbalance="samesessionloadbalance"/> <!-- 和本地bean一样实现服务 -->
<bean id="demoService" class="com.xxx.testdubbo.provider.DemoServiceImpl" /> </beans>

Consumer启动

public class Customer {
public static void main(String[] args){
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:customer.xml");
DemoService ds = (DemoService) ctx.getBean("demoService");
System.out.println(ds.saySomething("001"));
}
}

customer.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="consumer-of-helloworld-app" /> <!-- 使用zookeeper注册中心暴露发现服务地址 -->
<dubbo:registry address="zookeeper://10.130.41.36:2181" /> <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
<dubbo:reference id="demoService" interface="com.xxx.testdubbo.DemoService" />
</beans>

七.启动实例测试

Dubbo使用一些容错机制,里面会有一些判断。如下图所示:

当invoker只有一个那么就直接返回

当invoker有两个那么使用轮序机制

当有三个或三个以上的invoker时,才会触发loadbalance机制。

所以我们要启动三个Provider

更改provider.xml中Dubbo的监听端口为20880,20881,20882分别启动实例

在DemoServiceImpl中,每启动一个Provider实例,该方法返回相应的ip+端口号信息。

最后启动Customer,观察端口号结果。

八. 调试自定义LoadBalance

在项目里面一定引用了Dubbo的jar包,找到SameSessionIdLoadBalance文件,下断点,Consumer调试运行就可以了。

使用Dubbo的SPI扩展机制实现自定义LoadBalance——方法一 修改Dubbo源代码的更多相关文章

  1. 使用Dubbo的SPI扩展机制实现自定义LoadBalance——方法二 不改源码添加META-INF/dubbo元数据

    一.官网提供的方法 参考官网 http://dubbo.apache.org/zh-cn/docs/dev/impls/load-balance.html 二.方法总结 在工程中创建类并实现LoadB ...

  2. Dubbo中SPI扩展机制解析

    dubbo的SPI机制类似与Java的SPI,Java的SPI会一次性的实例化所有扩展点的实现,有点显得浪费资源. dubbo的扩展机制可以方便的获取某一个想要的扩展实现,每个实现都有自己的name, ...

  3. 理解 Dubbo SPI 扩展机制

    写在前面 最近接触了 gRPC 体会到虽然众多 RPC 框架各有各的特点但是他们提供的特性和功能有很多的相似之处 , 这就说明他们面对同样的分布式系统带来的问题.从 2016 年左右开始接触到 dub ...

  4. [转] 理解 Dubbo SPI 扩展机制

    写在前面 最近接触了 gRPC 体会到虽然众多 RPC 框架各有各的特点但是他们提供的特性和功能有很多的相似之处 , 这就说明他们面对同样的分布式系统带来的问题.从 2016 年左右开始接触到 dub ...

  5. 详解Apache Dubbo的SPI实现机制

    一.SPI SPI全称为Service Provider Interface,对应中文为服务发现机制.SPI类似一种可插拔机制,首先需要定义一个接口或一个约定,然后不同的场景可以对其进行实现,调用方在 ...

  6. Java中的SPI扩展机制(有demo)

    参考连接:https://www.jianshu.com/p/3a3edbcd8f24 一.什么是SPI SPI ,全称为 Service Provider Interface,是一种服务发现机制.它 ...

  7. Dubbo系列之 (一)SPI扩展

    一.基础铺垫 1.@SPI .@Activate. @Adaptive a.对于 @SPI,Dubbo默认的特性扩展接口,都必须打上这个@SPI,标识这是个Dubbo扩展点.如果自己需要新增dubbo ...

  8. 聊聊Dubbo - Dubbo可扩展机制实战

    1. Dubbo的扩展机制 在Dubbo的官网上,Dubbo描述自己是一个高性能的RPC框架.今天我想聊聊Dubbo的另一个很棒的特性, 就是它的可扩展性. 如同罗马不是一天建成的,任何系统都一定是从 ...

  9. dubbo的spi机制

    SPI SPI是一种扩展机制,在java中SPI机制被广泛应用,比如Spring中的SpringServletContainerInitializer 使得容器启动的时候SpringServletCo ...

随机推荐

  1. Arduino-接口图

    Arduino开发板上数字输入输出引脚中的3.5.6.9和11都提供0V和5V之外的可变输出.在这些引脚的旁边,会标有PWM——脉冲宽度调制,PWM是英文“Pulse Width Modulation ...

  2. dubbo和zikkeper的使用

    1.先来一段异常看看:No provider available for the service 16:05:25.755 [localhost-startStop-1] WARN o.s.w.c.s ...

  3. String总结

  4. Centos7 安装 tree

    Centos7 安装 tree 用命令 yum 安装  tree yum -y install tree

  5. Stm32复习之时钟系统

    地点:南图 这部分的内容是整个STM32学习知识的核心,不管是什么微控制器处理器,时钟系统都是其核心类似于人之心脏,因此学好理解这一章节至关重要. 为了便于理解这一系统,将从以下几个层次来讲.(忘了是 ...

  6. spring cloud 微服务调用--ribbon和feign调用

    这里介绍ribbon和feign调用两种通信服务调用方式,同时介绍如何引入第三方服务调用.案例包括了ribbon负载均衡和hystrix熔断--服务降级的处理,以及feign声明式服务调用.例子包括s ...

  7. Lua中的一些库(1)

    [数学库] 数学库(math)由一组标准的数学函数构成.这里主要介绍几个常用的函数,其它的大家可以自行百度解决. 三角函数(sin,cos,tan……)所有的三角函数都使用弧度单位,可以用函数deg( ...

  8. 金三银四背后,一个 Android 程序员的面试心得

    回顾一下自己这段时间的经历,九月份的时候,公司通知了裁员,我匆匆忙忙地出去面了几家,但最终都没有拿到offer,我感觉今年的寒冬有点冷.到十二月份,公司开始第二波裁员,我决定主动拿赔偿走人.后续的面试 ...

  9. 软件工程课开学测试——根据已有的CSS模板资源,搭建整个系统

    日期:2019.2.28 博客期:038 星期四 今天的测试得到了9.5分,将将及格的程度吧!本次程序完成的很不成功! <%@ page language="java" co ...

  10. UML——类图

    类图(Class diagram)主要用于描述系统的结构化设计.类图也是最常用的UML图,用类图可以显示出类.接口以及它们之间的静态结构和关系.在类图中一共包含了以下几种模型元素,分别是:类(Clas ...