遗留非springboot传统项目接入eureka注册与服务发现
来源:互联网 发布:ps美工教程视频 编辑:程序博客网 时间:2024/06/05 16:24
推荐: jeesuite开发框架,免费开源、一站式解决方案。
最近规划自动化运维以及统一监控需求,鉴于目前公司内部大部分项目采用spring cloud体系架构、另外还有一些老的传统spring web的项目,于是就考虑把老的项目通过低成本改造的方式接入spring cloud体系,也就是可以通过eureka注册和服务发现、通过zuul服务路由。
说干就干,通过eureka官方实例和研究spring boot注册eureka源码发现这个也很容易实现,所以废话不多说,直接贴代码了 。
首先加入项目依赖(maven为例)
<dependency> <groupId>com.netflix.eureka</groupId> <artifactId>eureka-client</artifactId> <version>1.4.12</version> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </exclusion> <exclusion> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </exclusion> <exclusion> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> </exclusion> <exclusion> <groupId>javax.ws.rs</groupId> <artifactId>jsr311-api</artifactId> </exclusion> </exclusions></dependency> <dependency> <groupId>com.netflix.archaius</groupId> <artifactId>archaius-core</artifactId> <version>0.7.4</version> <exclusions> <exclusion> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-core</artifactId> <version>1.2.6.RELEASE</version> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> </exclusion> </exclusions> </dependency>
加入配置文件
eureka.region=defaulteureka.registration.enabled=trueeureka.preferSameZone=trueeureka.shouldUseDns=falseeureka.serviceUrl.default=http://192.168.1.100:7861/eurekaeureka.decoderName=JacksonJsoneureka.name=demoeureka.vipAddress=${eureka.name}-serviceeureka.port=8081eureka.homePageUrl=http://192.168.1.101:${eureka.port}eureka.healthCheckUrl=http://192.168.1.101:${eureka.port}/service/healtheureka.statusPageUrl=http://192.168.1.101:${eureka.port}/service/info
- spring.cloud.client.ipAddress :为自定义变量
- healthCheckUrl,statusPageUrl接口可以不要,但是为了监控可以自己实现一个简单的接口即可
初始化eureka客户端
private void initEurekaClient() throws Exception{ Properties properties = new Properties(); InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("eureka.properties"); properties.load(inputStream); // properties.setProperty("eureka.ipAddr", IpUtils.getLocalIpAddr()); instanceId = properties.getProperty("eureka.ipAddr") + ":" + properties.getProperty("eureka.ipAddr") + "/" + properties.getProperty("eureka.name"); properties.setProperty("eureka.instanceId", instanceId); ConfigurationManager.loadProperties(properties); MyDataCenterInstanceConfig instanceConfig = new MyDataCenterInstanceConfig(); InstanceInfo instanceInfo = new EurekaConfigBasedInstanceInfoProvider(instanceConfig).get(); applicationInfoManager = new ApplicationInfoManager(instanceConfig, instanceInfo); DefaultEurekaClientConfig clientConfig = new DefaultEurekaClientConfig(); eurekaClient = new DiscoveryClient(applicationInfoManager, clientConfig);}
注册服务
private void waitForRegistrationWithEureka() { applicationInfoManager.setInstanceStatus(InstanceInfo.InstanceStatus.STARTING); try { Thread.sleep(2000); } catch (InterruptedException e) { } applicationInfoManager.setInstanceStatus(InstanceInfo.InstanceStatus.UP); long startTime = System.currentTimeMillis(); //开启一个线程验证注册结果 new Thread(new Runnable() { @Override public void run() { while (true) { if (System.currentTimeMillis() - startTime > VERIFY_WAIT_MILLIS) { log.warn(" >>>> service registration status not verify,please check it!!!!"); return; } try { List<InstanceInfo> serverInfos = eurekaClient.getInstancesByVipAddress(vipAddress, false); for (InstanceInfo nextServerInfo : serverInfos) { if (nextServerInfo.getIPAddr().equals(IpUtils.LOCAL_BACK_IP) || nextServerInfo.getIPAddr().equals(IpUtils.getLocalIpAddr())) { String instanceInfoJson = JsonUtils.getMapper().writerWithDefaultPrettyPrinter() .writeValueAsString(nextServerInfo); log.info("verifying service registration with eureka finished,instance:\n{}", instanceInfoJson); return; } } } catch (Throwable e) { } try { Thread.sleep(5000); } catch (Exception e1) { } log.info("Waiting 5s... verifying service registration with eureka ..."); } } }).start(); }
通过这几步就完成了eureka的注册,登录eureka控制台你将能看到对应注册信息。但是在zuul转发调用过程发现一个问题:无法识别hostname,如果你们的服务器之间没有做hostname同步就需要继续改造,于是就看了下springboot注册eureka有一个配置项eureka.instance.preferIpAddress,所以我们也可以模仿他的实现。于是在初始化客户端的时候我们需要这样改造:
MyDataCenterInstanceConfig instanceConfig = new MyDataCenterInstanceConfig(){ @Override public String getHostName(boolean refresh) { String hostName = super.getHostName(refresh); if(ResourceUtils.getBoolean("eureka.preferIpAddress")){ hostName = IpUtils.getLocalIpAddr(); } return hostName; } @Override public String getIpAddress() { return IpUtils.getLocalIpAddr(); }};
这样,注册的真实服务地址就是ip了。服务注册就搞定收工了。
接下来就是服务发现,及与其他springboot项目一样通过注册中心vipAddress互相调用。实际过程就是调用前去eureka拿一个真实地址替换vipAddress变量。
获取真实服务地址
public String getRealServerHost(String serviceId){ InstanceInfo serverInfo = eurekaClient.getNextServerFromEureka(serviceId, false); String realServerName = serverInfo.getIPAddr() + ":" + serverInfo.getPort(); return realServerName;}
下面是我实现的几个resttemplate
public class EurekaRestTemplateBuilder { private static Map<String, RestTemplate> restTemplates = new HashMap<>(); public static synchronized RestTemplate build(ClientHttpRequestInterceptor ...interceptors ){ return build("default", interceptors); } public static synchronized RestTemplate build(String name,ClientHttpRequestInterceptor ...interceptors ){ if(restTemplates.containsKey(name))return restTemplates.get(name); SimpleClientHttpRequestFactory factory = new EurekaClientHttpRequestFactory(); factory.setReadTimeout(15000);//ms factory.setConnectTimeout(5000);//ms RestTemplate restTemplate = new RestTemplate(factory); List<ClientHttpRequestInterceptor> interceptorList = new ArrayList<>(); interceptorList.add(new RestTemplateAutoHeaderInterceptor()); if(interceptors != null && interceptors.length > 0){ for (ClientHttpRequestInterceptor interceptor : interceptors) { interceptorList.add(interceptor); } } restTemplate.setInterceptors(interceptorList); // restTemplate.setErrorHandler(new CustomResponseErrorHandler()); // restTemplates.put(name, restTemplate); return restTemplate; } private static class EurekaClientHttpRequestFactory extends SimpleClientHttpRequestFactory{ @Override public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException { uri = convertToRealUri(uri); return super.createRequest(uri, httpMethod); } @Override public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) throws IOException { uri = convertToRealUri(uri); return super.createAsyncRequest(uri, httpMethod); } private URI convertToRealUri(URI uri){ String serviceId = uri.getHost(); try { String realHost = EurekaRegistry.getInstance().getRealServerHost(serviceId); uri = new URI(uri.toString().replace(serviceId, realHost)); return uri; } catch (Exception e) { throw new RuntimeException(e); } } }}
接下来就可以调用其他eureka注册服务了。
private RestTemplate restTemplate = EurekaRestTemplateBuilder.build(); public List<IdNamePair> getProvinces() { ParameterizedTypeReference<List<IdNamePair>> arearesponseType = new ParameterizedTypeReference<List<IdNamePair>>() { }; List<IdNamePair> lists = restTemplate .exchange("http://DEMO-SERVICE/region/provinces", HttpMethod.GET, null, arearesponseType) .getBody(); return lists; }
ZUUL转发配置
zuul.routes.demo.path=/demo/**zuul.routes.demo.serviceId=demo-service
到此,服务注册和服务发现都完成了。
有任何问题,请加技术群:230192763讨论
阅读全文
0 0
- 遗留非springboot传统项目接入eureka注册与服务发现
- Eureka服务注册与发现
- 1、Eureka实现服务注册与发现
- 使用 Eureka 实现服务注册与发现
- SpringCloud服务的注册与发现(Eureka)
- SpringCloud的服务注册与发现Eureka
- Spring-Cloud 服务注册与发现 Eureka
- Spring Cloud Eureka服务注册与发现
- springcloud eureka服务注册与发现
- Spring Cloud Eureka 服务注册与发现
- SpringBoot -- 服务注册与发现
- 2.服务注册中心(Eureka服务注册与发现)
- Eureka-服务注册于发现
- SpringBoot ,zookeeper 服务的注册与发现
- springcloud(第三篇)springcloud eureka 服务注册与发现
- springcloud(第一篇)springcloud eureka 服务注册与发现
- springcloud(第三篇)springcloud eureka 服务注册与发现 *****
- Spring Cloud 的Eureka服务注册与发现
- JavaFX笔记
- JS如何判断一个对象为空
- sophus库的一些使用
- MySql避免重复插入记录方法
- 解决ubuntu花屏的问题
- 遗留非springboot传统项目接入eureka注册与服务发现
- 使用Goolge开源工具zxing实现二维码读写工具(带Logo)
- 英文版Excel打开含中文的csv文件乱码的解决办法
- 纯CSS美化input radio和checkbox的样式
- 数据库——事务的ACID
- easydarwin原创文章
- 排序二叉树or搜索二叉树or查找二叉树
- java InputStream读取数据问题
- 4.1(2)写出运行结果