Spring Cloud Netflix子模块综合整理-Eureka

Spring Cloud Netflix特征

Spring Cloud Netflix功能:

  • 服务发现:可以注册Eureka实例,客户端可以使用Spring管理的bean发现实例
  • 服务发现:可以使用声明性Java配置创建嵌入式Eureka服务器
  • 断路器:Hystrix客户端可以使用简单的注释驱动方法装饰器构建
  • 断路器:带有声明性Java配置的嵌入式Hystrix仪表板
  • 声明性REST客户端:Feign创建使用JAX-RS或Spring MVC注释修饰的接口的动态实现
  • 客户端负载均衡器:Ribbon
  • 外部配置:从Spring Environment到Archaius的桥接(使用Spring Boot约定启用Netflix组件的本机配置)
  • 路由器和过滤器:Zuul过滤器的自动注册,以及反向代理创建的配置方法的简单

总结:Eureks实现服务注册和服务发现,Hystrix断路器提供服务降级和服务调用仪表板,fegin和ribbon提供复杂均衡,zuul提供统一网关过滤

            

 

1.服务发现:Eureka客户

Service Discovery是基于微服务的体系结构的关键原则之一。 尝试手动配置每个客户端或某种形式的约定可能非常困难,并且可能非常脆弱。 Eureka是Netflix服务发现服务器和客户端。 可以配置和部署服务器以使其具有高可用性,每个服务器将关于已注册服务的状态复制到其他服务器。

1.1如何添加Eureka客户端

<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

 

1.2注册Eureka

当客户端向Eureka注册时,它会提供有关自身的元数据,如主机和端口,运行状况指示器URL,主页等.Eureka从属于服务的每个实例接收心跳消息。 如果心跳故障超过可配置的时间表,则通常会从注册表中删除该实例

Example eureka client:

@Configuration
@ComponentScan
@EnableAutoConfiguration
@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);
   }
}

 

通过在类路径上安装spring-cloud-starter-netflix-eureka-client,您的应用程序将自动注册到Eureka Server,但必须配置Eureka Server相关信息。

application.yml

ureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/

 

从环境中获取的默认应用程序名称(服务ID)、虚拟主机和非安全端口是${spring.application.name}、${spring.application.name}和${server.port}。

要禁用Eureka Discovery Client,您可以将eureka.client.enabled设置为false

1.3使用Eureka Server进行身份验证

Eureka Server默认是允许匿名访问的,可通过增加Spring-boot-starter-security来添加基于身份认证

Eureka Server 配置

security:
 basic:
  enabled:true
user:
 name:admin
 password:123456

 

如上就为Eureka Server添加了基于HTTP basic的认证。如果不设置name和password,默认name为user,password会在项目启动的时候随机生成并且打印到控制台。

Eureka client 配置

ureka:
client:
serviceUrl:
defaultZone: http://admin:123456@localhost:8761/eureka/

 

如果其中一个eureka.client.serviceUrl.defaultZone URL中嵌入了身份验证(如http:// user:password @ localhost:8761/ eureka),HTTP基本身份验证将自动添加到您的eureka客户端

1.4状态页面和健康指标

Eureka实例的状态页面和运行状况指示器分别默认为“/ info”和“/ health”,它们是Spring Boot Actuator应用程序中提供的HTTP访问端点。 如果使用非默认上下文路径或servlet路径(例如,server.servletPath = / foo,这样访问路径为http://ip:port/foo/info)或管理端点路径,则需要更改这些,即使对于Actuator应用程序也是如此(例如,这样访问路径为http://ip:port/admin/info)

application.yml

management:
    contextPath = /admin
eureka:
 instance:
    statusPageUrlPath: ${management.context-path}/info
    healthCheckUrlPath: ${management.context-path}/health

 

1.5注册安全应用程序

如果您的应用程序想通过HTTPS通信,您可以在EurekaInstanceConfig中设置两个标志,即eureka.instance.[nonSecurePortEnabled,securePortEnabled] = [false,true]。 这将使Eureka发布实例信息,显示出对安全通信的明确偏好。 对于以这种方式配置的服务,Spring Cloud DiscoveryClient将始终返回以https开头的URI,并且Eureka(本机)实例信息将具有安全的运行状况检查URL。由于Eureka在内部工作的方式,它仍将发布非 状态和主页的安全URL,除非您也明确覆盖这些URL。 您可以使用占位符来配置eureka实例URL,例如

ureka:
instance:
statusPageUrl: https://${eureka.hostname}/info
healthCheckUrl: https://${eureka.hostname}/health
homePageUrl: https://${eureka.hostname}/

 

请注意,$ {eureka.hostname}是一个本机占位符,仅在更高版本的Eureka中可用。 您也可以使用Spring占位符实现相同的功能,例如 使用$ {eureka.instance.hostName}

1.6Eureka健康检查

默认情况下,Eureka使用客户端心跳来确定客户端是否已启动。 除非另有说明,否则Discovery Client不会根据Spring Boot Actuator传播应用程序的当前运行状况检查状态。 这意味着在成功注册后,Eureka将始终宣布应用程序处于“UP”状态。 通过启用Eureka运行状况检查可以更改此行为,从而将应用程序状态传播到Eureka。 因此,每个其他应用程序将不会在“UP”之外的状态下向应用程序发送流量。

需要引入Spring-Boot-Actuator

ureka:
  client:
    healthcheck:
      enabled: true

 

eureka.client.healthcheck.enabled = true应该只在application.yml中设置。 在bootstrap.yml中设置值将导致不良副作用,例如在具有UNKNOWN状态的eureka中注册。

1.7Eureka元数据

花点时间了解Eureka元数据是如何工作的是值得的,因此您可以在您的平台中以一种有意义的方式使用它。有一些标准的元数据,比如主机名、IP地址、端口号、状态页面和健康检查。它们发布在服务注册中心中,客户端使用它们以一种简单的方式联系服务。可以将附加的元数据添加到eurekar .instance.metadataMap,这在远程客户机中是可以访问的,但是通常不会改变客户机的行为,除非它知道元数据的含义。下面描述了一些特殊情况,Spring Cloud已经为元数据映射赋予了意义。

1.8更改Eureka实例ID

在原生的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中提供唯一标识符来覆盖模式的设置,比如在本地进行客户端负载均衡调试时,需要启动多个服务实例,如果我们直接启动同一个应用必然会导致端口冲突。虽然可以在命令行中通过--server.port指定端口,但这样显得比较麻烦。实际上可以通过使用随机数server.port=${random.in[10000,19999]}来让tomcat启动采用随机端口。但是这个时候会发现注册到Eureka Sever的实例名是相同的,这会使得只有一个服务实例能够正常提供服务。对于这个问题,可以通过如下设置来解决

application.yml

eureka:
  instance:   
     instanceId:${spring.application.name}:${random.int}

 

1.9用EurekaClient

使用EurekaClient获取Eureka server中的实例,EurekaClient是com.netflix.discovery.EurekaClient原生提供的(而不是Spring Cloud DiscoveryClient)

@Autowired
private EurekaClient discoveryClient;
public String serviceUrl() {
   InstanceInfo instance = discoveryClient.getNextServerFromEureka("STORES", false);
   return instance.getHomePageUrl();
}

 

1.10原生Netflix EurekaClient的替代品

您不必使用原始的Netflix EurekaClient,通常在某种包装器后面使用它会更方便。 Spring Cloud使用逻辑Eureka服务标识符而不是物理URL支持Feign(REST客户端构建器)和Spring RestTemplate[即在spring Cloud中服务之间的调用是通过服务名service id 调用的而不是通过具体的URL]。 要使用固定的物理服务器列表配置功能区,只需将<client> .ribbon.listOfServers[进行负载均衡轮训设置]设置为逗号分隔的物理地址(或主机名)列表,其中<client>是客户端的ID。

您还可以使用org.springframework.cloud.client.discovery.DiscoveryClient,它为不特定于Netflix的发现客户端提供简单的API,例如

@Autowired
private DiscoveryClient discoveryClient;
public String serviceUrl() {
    List<ServiceInstance> list = discoveryClient.getInstances("STORES");
    if (list != null && list.size() > 0 ) {
         return list.get(0).getUri();
    }
    return null;
}

 

1.11为什么注册服务这么慢?

作为一个实例还涉及到注册表的周期心跳(通过客户端的serviceUrl),默认持续时间为30秒。直到实例、服务器和客户端在其本地缓存中都有相同的元数据(因此可能需要3次心跳),客户端才能发现服务。 您可以使用eureka.instance.leaseRenewalIntervalInSeconds更改周期,这将加快将客户端连接到其他服务的过程。 在生产中,最好坚持使用默认值,因为服务器内部有一些计算可以对租约续订期做出假设。

2.服务发现:Eureka Server

2.1 如何添加 Eureka Server

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>

2.2 如何运行 Eureka Server

@SpringBootApplication
@EnableEurekaServer
public class Application {
    public static void main(String[] args) {
    new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}

 

Eureka Server有一个带有UI的主页,以及/eureka/ *下正常的Eureka功能的HTTP API端点.通过http://ip:host 可以查看

2.3 高可用 Zones 和 Regions


Eureka服务器没有后端存储注册表的信息,但注册表中的服务实例都必须发送心跳以使其注册保持最新(因此可以在内存中完成)。 客户端还具有eureka注册的内存缓存(因此,对于服务的每个请求,他们不必访问注册表)。

默认情况下,每个Eureka服务器也是Eureka客户端,并且需要(至少一个)服务URL来定位对等体。Eureka Server的高可用实际上就是将自己作为服务想其他服务注册中心注册,这样就形成了一组互相注册的服务注册中心,以实现服务清单的相互同步,达到高可用效果。

2.4 独立模式---不将自己作为服务注册到注册中心

两个缓存(客户端和服务器)和心跳的组合使得一个独立的Eureka服务器对失败具有相当强的恢复能力,只要有某种监视器或弹性运行时保持它的活性。在独立模式下,您可能更喜欢关闭客户端行为,这样它就不会继续尝试,也不会无法到达它的同行。

server:
    port: 8761
eureka:
    instance:
    hostname: localhost
    client:
    registerWithEureka: false   //将自己作为服务注册到注册中心
    fetchRegistry: false
    serviceUrl:
       defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

 

2.5Eureka Server相互注册

通过运行多个实例并要求它们相互注册,可以使Eureka更具弹性和可用性。 实际上,这是默认行为,因此您需要做的就是将有效的serviceUrl添加到对等方,例如

application-peer1.yml

eureka:
 instance:
   hostname: peer1
 client:
  serviceUrl:
    defaultZone: http://peer2/eureka/

 

application-peer2.yml

eureka:
  instance:
     hostname: peer2
  client:
  serviceUrl:
    defaultZone: http://peer1/eureka/

 


在上面例子中,我们有两个YAML文件,可以通过不同的Spring配置文件模拟两个主机运行同一服务。您可以使用此配置来测试单个主机上的对等意识(即Eureka Server相互注册实现高可用,在生产中这样做没有多大价值),通过操作/etc/hosts来解析主机名

2.6 IP地址作为主机标识

默认是通过主机名(hostname作为标识的)在某些情况下,你可能希望用IP地址而不是主机名。 将eureka.instance.preferIpAddress设置为true,当应用程序向eureka注册时,它将使用其IP地址而不是其主机名。

如果Java无法确定主机名,则将IP地址发送给Eureka。 设置主机名的唯一方法是使用eureka.instance.hostname。 例如,您可以使用环境变量在运行时设置主机名eureka.instance.hostname=$ {HOST_NAME}

 

 微信公众号

 

 

posted @ 2020-01-14 09:22  盲目的拾荒者  阅读(312)  评论(0编辑  收藏  举报