一. 拉取源码
到 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 调试运行就可以了.
来源: https://www.cnblogs.com/Sicwen/p/10573617.html