Spring cloud微服务注册Eureka时指定端口或服务地址
Spring cloud各个微服务使用过程中,通过Eureka进行服务的注册与发现。ZUUL网管及服务间请求调用,默认都是通过Eureka进行。 服务间请求处理过程,一般是通过服务名,到Eureka中获取实际的服务请求地址,然后根据实际地址进行HTTP请求。 默认情况下,通过服务名到Eureka获取服务所在地址一般是如下构成的: http://${eureka...
Spring cloud各个微服务使用过程中,通过Eureka进行服务的注册与发现。ZUUL网管及服务间请求调用,默认都是通过Eureka进行。
服务间请求处理过程,一般是通过服务名,到Eureka中获取实际的服务请求地址,然后根据实际地址进行HTTP请求。
默认情况下,通过服务名到Eureka获取服务所在地址一般是如下构成的:
http://${eureka.instance.hostName}:${server.port}/
但是在微服务部署过程中,Docker镜像部署是我们常用的部署方式,这样就可能会出现一种情况,由于一些特殊的原因,docker映射出来的访问端口跟应用端口(server.port)不一致,如果我们注册Eureka上的服务端口还是应用端口(server.port)的话,服务间请求调用将会报链接超时(connect timed out),请求不到相应服务。这种情况也经常发生在Docker部署到K8s时,服务端口与应用端口通常由于端口冲突会不一样。
如何解决呢?
- Eureka已经考虑到了各种部署情况,在Cloud Foundry上使用时,服务有全局的路由,故注册服务时也需要定制服务端口,情况类似,定制方式如下:
eureka:
instance:
hostname: ${vcap.application.uris[0]}
nonSecurePort: 80
可见,通过设置eureka.instance.nonSecurePort来指定服务端口,这样就可以解决服务端口与应用端口(server.port)不一致情况。
- Eureka注册时还有一个参数,定制完整的服务URL,这个服务URL就是服务间通过服务名在Eureka中获取的服务地址,其配置如下:
eureka: instance: homePageUrl: http://${eureka.hostname}:8009/
如果Spring boot的application.yml中配置了eureka.instance.homePageUrl地址,则根据服务名在Eureka中获取的服务地址就是eureka.instance.homePageUrl配置的地址。
-
Eureka还支持服务间HTTPS请求,其配置如下:
eureka: instance: securePortEnabled: true statusPageUrl: https://${eureka.hostname}/info healthCheckUrl: https://${eureka.hostname}/health homePageUrl: https://${eureka.hostname}/
这样通过服务名Eureka返回地址就是HTTPS加密请求的URL。
-
Eureka定制能力很强具体,可以参考官方文档:http://cloud.spring.io/spring-cloud-static/Finchley.SR1/single/spring-cloud.html#_eureka_metadata_for_instances_and_clients,里面详细介绍比较全面的配置,通常在遇到问题时作为字典使用,不过在时间允许的情况下还是可以详细了解一下,避免走各种弯路。
如何验证配置的服务地址已生效呢?Eureka提供了EurekaClient请求接口,便于我们交互,我们可以通过该接口,获取Eureka提供的各种能力,满足我们业务需要,其中服务注册与服务发现接口应该是最常用的了。通过EurekaClient提供了扩展能力。所以我们可以通过EurekaClient接口,使用服务名获取服务请求地址。示例如下:
package com.king.business.controller;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
@RestController
public class BusinessController {
private final static Logger LOG = LoggerFactory.getLogger(BusinessController.class);
@Autowired
private EurekaClient discoveryClient;
@RequestMapping(path="/getServiceUrl/{servicename}", method=RequestMethod.GET)
public String getServiceUrl(@PathVariable("servicename") String serviceName) {
InstanceInfo instance = discoveryClient.getNextServerFromEureka(serviceName, false);
String serviceUrl = "";
if(null != instance) {
serviceUrl = instance.getHomePageUrl();
}
return serviceUrl;
}
}
其请求结果如下所示:
更多推荐
所有评论(0)