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>