Netflix:提供了很多组件来构建大型分布式系统,包括服务发现(Eureka)、断路器(Hystrix)、智能路由(Zuul)和客户端负载平衡(Ribbon)。
引用依赖:
group ID:org.springframework.cloud
artifact ID: spring-cloud-starter-netflix-eureka-client
客户端向Eureka注册时,提供了自身的元数据(host、port、健康指示的url、主页和其他详细信息),Eureka会通过心跳机制检测各实例的状态,如果超过配置时间没得到心跳,Eureka会认为实例挂掉了,会从注册表中删除实例。
下面的例子展示了一个最小的Eureka客户端应用程序:
@SpringBootApplication
@RestController
public class Application {
@RequestMapping("/")
public String home() {
return "Hello world";
}
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
application.yml
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
设置eureka.client.enabled
为false禁止Eureka来发现服务。当spring.cloud.discovery.enabled
设置为false的时候,Eureka也不会去发现客户端。
user:password@localhost:8761/eureka
格式配置eureka.client.serviceUrl.defaultZone,HTTP基本身份验证将自动添加到您的eureka客户机中。 或者可以创建一个DiscoveryClientOptionalArgs bean,并注入ClientFilter实例。
application.yml
eureka:
instance:
statusPageUrlPath: ${server.servletPath}/info #状态监测
healthCheckUrlPath: ${server.servletPath}/health #健康监测
下面两个配置让Eureka发布的时候以HTTPS的方式发布:
eureka.instance.[nonSecurePortEnabled]=[false]
eureka.instance.[securePortEnabled]=[true]
由于Eureka的内部工作方式,它仍然为状态和主页发布不安全的URL,除非您也显式地覆盖它们。您可以使用占位符来配置eureka实例url,如下例所示:
application.yml
eureka:
instance:
statusPageUrl: https://${eureka.hostname}/info
healthCheckUrl: https://${eureka.hostname}/health
homePageUrl: https://${eureka.hostname}/
默认情况下,Eureka使用客户端心跳来确定客户端是否启动。除非另有说明,否则发现客户端不会根据SpringBootActuator传播应用程序的当前健康检查状态。因此,在成功注册之后,尤里卡总是会宣布应用程序处于“UP”状态。可以通过启用Eureka健康检查来更改此行为,这将导致将应用程序状态传播到Eureka。因此,所有其他应用程序都不会将流量发送到除“UP”以外的其他状态的应用程序。下面的示例展示了如何使用:
application.yml
eureka:
client:
healthcheck:
enabled: true
注意该配置智能配置在application.yml中,配置在bootstrap.yml中会导致注册到Eureka后状态是UNKNOWN 。
如果您需要对健康检查进行更多的控制,请考虑实现您自己的com.netflix.appinfo.HealthCheckHandler。
一个普通的Netflix Eureka实例注册的ID等于它的主机名(也就是说,每个主机只有一个服务)。Spring Cloud Eureka提供了一个合理的默认值,其定义如下:
${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}}}
例如:myhost:myappname:8080
使用Spring cloud,可以通过eureka.instance.instanceId来覆盖默认值:
application.yml
eureka:
instance:
instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
一旦您有了一个发现客户机应用程序,就可以使用它从Eureka服务器发现服务实例。一种方法是使用本地的com.netflix.discovery.EurekaClient(与Spring Cloud DiscoveryClient相反),如下面的示例所示:
@Autowired
private EurekaClient discoveryClient;
public String serviceUrl() {
InstanceInfo instance = discoveryClient.getNextServerFromEureka("STORES", false);
return instance.getHomePageUrl();
}
默认情况下,EurekaClient使用Jersey进行HTTP通信。如果希望避免Jersey的依赖项,可以将其排除在依赖项之外。Spring Cloud基于Spring RestTemplate自动配置传输客户机。看下面:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-apache-client4</artifactId>
</exclusion>
</exclusions>
</dependency>
作为一个实例还涉及到到注册中心的一个周期心跳(通过客户机的serviceUrl),默认持续时间为30秒。只有当实例、服务器和客户端在其本地缓存中都具有相同的元数据时,客户端才能发现服务(因此可能需要3次心跳)。
eureka.client.refresh.enable=false #禁止eureka客户端刷新
group ID: org.springframework.cloud
artifact ID:spring-cloud-starter-netflix-eureka-server
@SpringBootApplication
@EnableEurekaServer
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
服务器有一个主页,在/ Eureka /*下有用于正常Eureka功能的UI和HTTP API端点。
Eureka服务器没有后端存储,但是注册表中的服务实例都必须发送心跳来保持它们的注册是最新的(所以这可以在内存中完成)。客户端也有一个Eureka注册的内存缓存(这样他们就不必为每个服务请求都去注册)。
默认情况下,每个Eureka服务器也是一个Eureka客户端,需要(至少一个)服务URL来定位一个对等点。如果您不提供它,服务就会运行并正常工作,但是它会使您的日志充满许多关于不能向对等方注册的噪音。
这两个缓存(客户端和服务器)和心跳的组合使一个独立的Eureka服务器具有相当强的故障恢复能力,只要有某种监视器或弹性运行时(如Cloud Foundry)使它保持活动状态。在独立模式下,您可能更希望关闭客户端行为,这样它就不会一直尝试,也不会失败。下面的例子演示了如何关闭客户端行为:
application.yml (Standalone Eureka Server)
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
注意,serviceUrl指向与本地实例相同的主机。
通过运行多个实例并让它们彼此注册,Eureka可以变得更有弹性和可用性。实际上,这是默认的行为,所以您需要做的只是向对等节点添加一个有效的serviceUrl,如下面的示例所示:
application.yml (Two Peer Aware Eureka Servers)
---
spring:
profiles: peer1
eureka:
instance:
hostname: peer1
client:
serviceUrl:
defaultZone: https://peer2/eureka/
---
spring:
profiles: peer2
eureka:
instance:
hostname: peer2
client:
serviceUrl:
defaultZone: https://peer1/eureka/
在前面的示例中,我们有一个YAML文件,可以通过在不同的Spring配置文件中运行它来在两个主机(peer1和peer2)上运行相同的服务器。您可以通过操作/etc/hosts来解析主机名,从而使用此配置测试单个主机上的对等点感知(在生产环境中这样做没有多大价值)。实际上,如果您运行的机器知道自己的主机名(默认情况下,使用java.net.InetAddress
查找),则不需要eureka.instance.hostname
。
您可以将多个对等点添加到一个系统中,并且只要它们都通过至少一条边彼此连接,它们就会在彼此之间同步注册。如果对等点在物理上是分开的(在一个数据中心内或在多个数据中心之间),那么在原则上,系统可以在“split-brain”类型的故障中幸存下来。您可以向系统中添加多个对等点,只要它们彼此都直接连接,它们就会在彼此之间同步注册。
application.yml (Three Peer Aware Eureka Servers)
eureka:
client:
serviceUrl:
defaultZone: https://peer1/eureka/,http://peer2/eureka/,http://peer3/eureka/
---
spring:
profiles: peer1
eureka:
instance:
hostname: peer1
---
spring:
profiles: peer2
eureka:
instance:
hostname: peer2
---
spring:
profiles: peer3
eureka:
instance:
hostname: peer3
eureka.instance.preferIpAddress = true #以ip的形式发布,而不是主机名
只需通过Spring -boot-starter- Security
将Spring Security添加到服务器的类路径中,就可以保护Eureka服务器。默认情况下,当Spring Security在类路径上时,它将要求在向应用程序发送每个请求时发送一个有效的CSRF令牌。Eureka客户端通常不会拥有有效的跨站请求伪造(CSRF)令牌,您需要禁用/ Eureka /**端点的这个要求。例如:
@EnableWebSecurity
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().ignoringAntMatchers("/eureka/**");
super.configure(http);
}
}
For more information on CSRF see the Spring Security documentation.
A demo Eureka Server can be found in the Spring Cloud Samples repo.
spring-cloud-starter-netflix-eureka-server
和spring-cloud-starter-netflix-eureka-client
附带了一个spring-cloud-starter-netflix-ribbon
。由于Ribbon负载均衡器现在处于维护模式,我们建议改用Spring Cloud LoadBalancer,它也包含在Eureka启动器中。
pring.cloud.loadbalancer.ribbon.enabled = false #禁用ribbon负载均衡
也可以从maven依赖中去除ribbon依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</exclusion>
<exclusion>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-eureka</artifactId>
</exclusion>
</exclusions>
</dependency>
Eureka服务器所依赖的JAXB模块在JDK 11中被删除。如果您打算在运行Eureka服务器时使用JDK 11,则必须在POM或Gradle文件中包含这些依赖项。
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency>