到Dubbo官網 https://github.com/apache/incubator-dubbo/tree/2.5.x 下載源碼,解壓。git
選擇解壓後的源碼目錄,一路點擊nextgithub
在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就是該負載均衡的名字。spring
打開終端控制檯執行mvn clean install -Dmaven.test.skipapache
最後會在maven的本地倉庫中生成jar包session
能夠經過360解壓縮查看jar包中的class文件,看看咱們的代碼是否編譯進去了。架構
公共接口併發
public interface DemoService { String saySomething(String msg); }
provider實現該接口app
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,觀察端口號結果。
在項目裏面必定引用了Dubbo的jar包,找到SameSessionIdLoadBalance文件,下斷點,Consumer調試運行就能夠了。
歡迎關注+點擊連接加入羣聊【架構華山論劍836442475】:https://jq.qq.com/?_wv=1027&k=59k1QB9,進個人私人羣討論技術和學習!
羣內有大牛架構師分享經驗,Dubbo、Redis、Netty、zookeeper、Spring cloud、分佈式、高併發等架構技術,歡迎進羣一塊兒討論哦!專用於學習交流技術、分享面試機會,拒絕廣告,我也會在羣內不按期答題、探討。