1 InvokeFilter,實現此接口 能夠在consumer端 與provider端的調用過程當中攔截住請求調用。git
已經實現的InvokeFilter包括github
RetryInvokeFilter:實現失敗重試功能,固然須要provider端對應方法保證冪等性(吐槽下dubbo,dubbo的failover就是用重試來實現的,若是服務提供方不能安全重試會出問題的,因此通常dubbo reties都設置爲0,也就是說關閉了failover)緩存
ClusterInvokeFilter:實現jremoting的failover功能,這裏對dubbo的實現多了改進把retry與failover兩個概念區分對待 。failover是在明確知道對方沒有收到請求才換其餘provider重試。 其中包括(創建鏈接失敗,發送網絡請求包失敗,provider 服務器線程池慢明確返回server busy,或者服務不可用安全
後續的限流(TpsInvokeFilter), 統計監控,日誌均可以用攔截機制實現。能夠攔截同步調用,也能夠攔截異步調用服務器
public interface InvokeFilter { InvokeFilter getNext(); void setNext(InvokeFilter next); void setPrev(InvokeFilter prev); InvokeFilter getPrev(); Object invoke(Invoke invoke); Object beginInvoke(Invoke invoke); void endInvoke(Invoke invoke, Object result); }
另外一個擴展點事註冊中心Registry網絡
public interface Registry { void start(); void close(); List<ServiceProvider> getProviders(Invoke invoke); Map<String, ServiceProvider> getLocalProviders(); String getGlobalConfig(String fileName); String getAppConfig(String appName, String fileName); String getServiceConfig(String serviceName, String fileName); void publish(ServiceProvider provider); void unpublish(ServiceProvider provider); void subscribe(ServiceConsumer consumer); void unsubscribe(ServiceConsumer consumer); void addListener(RegistryListener listener); } public interface RegistryListener { void onEvent(RegistryEvent event); } public class RegistryEvent { public enum EventType { PROVIDERS_CHANGED, GLOBAL_CONFIG_CHANGED, APP_CONFIG_CHANGED, SERVICE_CONFIG_CHANGED, RECOVER } private EventType type; private String appName; private String serviceName; private String fileName; private String newContent; private List<ServiceProvider> newProviders; private String serviceId; //.....省略get,set }
此處能夠對註冊中心進行包裝。攔截住註冊中心的發佈,訂閱 ,獲取可用provider列表,實現服務的分組,路由,權重,緩存app
這裏採用了 裝飾器與觀察者的組合模式來來處理註冊中心的邏輯異步
首先在最原始的zookeeperRegistry上包裝上CacheRegistryWrapper實現動態配置 ,服務可用列表的本地緩存。經過監聽註冊中心的change事件來刷新緩存ide
而後再外層包裝上分組,路由,權重等功能 每一個包裝器內部都儘可能緩存計算結果,並經過監聽器來獲取最新配置刷新緩存spa
具體實現參考:
<bean id="registry" class="com.github.jremoting.route.RouteRegistryWrapper"> <constructor-arg> <bean class="com.github.jremoting.group.GroupRegistryWrapper"> <constructor-arg> <bean class="com.github.jremoting.registry.CacheRegistryWrapper"> <constructor-arg> <bean class="com.github.jremoting.registry.ZookeeperRegistry"> <constructor-arg name="zookeeperConnectionString" value="127.0.0.1:2181" /> </bean> </constructor-arg> </bean> </constructor-arg> </bean> </constructor-arg> </bean>