这几天又学到了新知识:dubbo框架
此框架很好的解决了我之前的Netty微服务框架中遇到的服务注册、管理的问题。于是拿来学学
官网地址:http://dubbo.io/
1、服务端的配置:
dubbo可以与spring良好的结合,所以服务端的配置就比较简洁:
<dubbo:application name="match-provider" /> <dubbo:protocol name="dubbo" serialization="fastjson" charset="utf-8"/> <dubbo:registry address="redis://${ds.redis.url}:6379" /> <dubbo:annotation package="com.xinou.lolttery.server.dubbo" />
在这里使用了dubbo协议,fastjson做序列化。默认也是使用netty作为服务器。
其实最开始使用的是默认的协议和序列化。但是会出现Class not found的错误。原因在于原来为了便于管理json,返回数据使用各种实体bean组合,在默认的序列化情况下包含了java类的信息,会导致客户端找不到此实体类。
为了和原代码保持一致,于是决定使用fastjson。
注册中心用redis,单纯是因为现在有一个redis服务。官方并不推荐使用。以后会考虑换用zookeeper
在具体的实现类中的注解如下:
@Service(version="1.0",interfaceClass = MatchService.class) public class MatchServiceImpl implements MatchService {
MatchService接口放在common项目下,被生产者和消费者共同依赖。
要注意这个Service注解并不是spring的注解,而是dubbo包下的注解。version也很重要,最开始的时候遇到了双方版本号不一致(1.0.0与1.0)导致找不到服务的情况。
如此想来依赖版本号对于未来的版本管理也是甚好的。
剩下的代码就和正常的服务入口代码一样了。
2、客户端
客户端的问题在于不一定使用spring框架。
于是仿照官网的api调用,自己写了一个客户端工具,每次需要服务的时候只要如main函数中调用即可。省去了自己满世界找服务地址的麻烦。
/** * dubbo分布式服务客户端 * Created by shizhida on 16/4/1. */ public class DubboClient { public static void main(String[] args) { MatchService matchService = DubboClient.getInstance().getService(MatchService.class); System.out.println(matchService.listMatchByTime(1,1)); } static class inner{ public static DubboClient client = new DubboClient(); } public static DubboClient getInstance(){ return inner.client; } //连接缓存 private Map<Class,ReferenceConfig> configpool = new ConcurrentHashMap<>(); //服务缓存 private Map<Class,Object> servicepool = new ConcurrentHashMap<>(); private ApplicationConfig application; private RegistryConfig registry; public <T> T getService(Class<T> clazz){ //直接从服务缓存池中取出 if(servicepool.containsKey(clazz)){ return (T) servicepool.get(clazz); } //若是服务缓存池中没有,检查连接缓存池并生成一个新的服务 else if(configpool.containsKey(clazz)){ ReferenceConfig<T> referenceConfig = configpool.get(clazz); return referenceConfig.get(); } //若连接缓存池中也没有,则生成一个新的连接并生成新的服务 else { ReferenceConfig<T> referenceConfig = genReferenceConfig(clazz); T service = referenceConfig.get(); servicepool.put(clazz,service); return service; } } private <T> ReferenceConfig<T> genReferenceConfig(Class<T> clazz) { ReferenceConfig<T> reference = new ReferenceConfig<>(); // 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏 reference.setApplication(application); reference.setRegistry(registry); // 多个注册中心可以用setRegistries() reference.setInterface(clazz); reference.setVersion("1.0"); configpool.put(clazz,reference); return reference; } private DubboClient(){ application = new ApplicationConfig(); application.setName("common-client"); // 连接注册中心配置 registry = new RegistryConfig(); registry.setAddress("redis://192.168.3.9:6379"); } }