目錄
本地調用
- 使用場景
本地調用使用Injvm協議,是一個僞協議,它不開啓端口,不發起遠程調用,只在JVM內直接關聯,但執行Dubbo的Filter鏈。
- 配置
//定義injvm協議
<dubbo:protocol name="injvm" />
//設置默認協議
<dubbo:provider protocol="injvm" />
//爲服務設置協議
<dubbo:service protocol="injvm" />
//優先使用injvm,暴露服務與引用服務都要聲明injvm="true"
<dubbo:consumer injvm="true" />
<dubbo:provider injvm="true" />
<dubbo:reference injvm="true" />
<dubbo:service injvm="true" />
//從Dubbo 2.2.0開始,每個服務都會在本地暴露,引用服務的時候,默認優先引用本地服務,如果想要引用遠程//服務,可以配置強制使用遠程服務
<dubbo:reference scope="remote" />
參數回調
- 使用場景
參數回調方式與調用本地callback或listener相同,只需要在Spring的配置文件中聲明哪個參數是callback類型即可,Dubbo將基於長連接的方式生成反向代理,這樣就可以從服務端調用客戶端邏輯。
- 配置
(1)共享服務接口
//服務接口實例:
public interface CallBackService{
void addListener(String key,CallbackListener listener);
}
public interface CallbackListener{
void changed(String msg);
}
(2)服務提供者接口實現
//服務提供者接口實現實例:
public class CallbackServiceImpl implements CallbackService{
private final Map<String,CallbackListener> listeners = new ConcurrentHashMap<String,CallbackListener>();
public CallbackServiceImpl(){
Thread t = new Thread(new Runnable(){
public void run(){
while(true){
try{
for(Map.Entry<String,CallbackListener> entry:listeners.entrySet()){
entry.getValue().changed(getChanged(entry.getKey()));
}
}catch(Throwable t){
t.printStackTrace();
}
}
}
}
);
}
}
public void addListener(String key,CallbackListener listener){
listeners.put(key,listener);
listener.changed(getChanged(key));
}
private String getChanged(String key){
return "Changed:" + new SimpleDateFormat("yyyy-MM-dd").format(new Date());
}
(3)服務提供者配置:
<bean id="callbackService" class="com.callback.CallbackServiceImpl" />
<dubbo:service interface="com.callback.CallbackService" ref="callbackService" connections="1" callbacks="1000">
<dubbo:method name="addListener">
<dubbo:argument index="1" callback="true" />
//也可以通過指定類型的方式
//<dubbo:argument type="com.demo.CallbackListener" callback="true" />
</dubbo:method>
</dubbo:service>
(4)服務消費者
//配置
<dubbo:reference id="callbackService" interface="com.callback.CallbackService" />
//消費者調用
CallbackService callbackService = (CallbackService) context.getBean("callbackService");
callbackService.addListener("foo.bar",new CallbackListener(){
public void changed(String msg){
System.out.println("callback1:" + msg);
}
});
事件通知
- 使用場景
在調用之前或調用之後出現異常時,會觸發oninvoke,onreturn,onthrow三個事件,可以配置當事件發生時,通知哪個類的哪個方法。
(1)服務提供者與消費者共享服務接口:
interface IDemoService{
public Person get(int id);
}
(2)服務提供者實現:
class NormalDemoService implements IDemoSerivce{
public Person get(int id) {
return new Person(id,"tigerJay",4);
}
}
(3)服務提供者配置:
<dubbo:application name="rpc-callback-demo" />
<dubbo:registry address="10.101.102.111" />
<bean id="demoService" class="com.demo.NormalDemoService" />
<dubbo:service interface="com.demo.IDemoService" ref="demoService" version="1.0.0" group="cn" />
(4)服務消費者Callback接口及實現:
interface Notify{
public void onreturn(Person msg,Integer id);
public void onthrow(Throwable ex,Integer id);
}
class NotifyImpl implements Notify{
public void onreturn(Person msg,Integer id){
System.out.println("onreturn:" + msg);
}
public void onthrow(Throwable ex,Integer id){
errors.put(id,ex);
}
}
(5)消費服務者Callback接口及實現
<bean id="demoCallback" class="com.demo.NotifyImpl" />
<dubbo:reference id="demoService" interface="com.demo.IDemoService" version="1.0.0" group="cn">
<dubbo:method name="get" async="true" onreturn="demoCallback.onreturn" onthrow="demoCallback.onthrow" />
</dubbo:reference>
(6)注意:
- oninvoke方法:
- 必須具有與真實的被調用方法相同的入參列表
- onreturn方法:
- 至少要有一個入參且第一個入參必須與get()方法的返回類型相同(也就是Person),接收返回結果:例如,onreturn(Person msg)
- 可以有多個參數,多個參數的情況下,第一個後邊的所有參數都是用來接收get(Integer id)入參的:例如, onreturn(String result, Integer id)
- onthrow方法:
- 至少要有一個入參且第一個入參類型爲Throwable或其子類,接收返回結果;例如,onthrow(Throwable ex)
- 可以有多個參數,多個參數的情況下,第一個後邊的所有參數都是用來接收get(Integer id)方法入參的:例如,onthrow(Throwable ex, Integer id)
- 如果是consumer在調用provider的過程中,出現異常時不會走onthrow方法的,onthrow方法只會在provider返回的RpcResult中含有Exception對象時,纔會執行。(dubbo中下層服務的Exception會被放在響應RpcResult的exception對象中傳遞給上層服務)