一、啥是服务治理
服务治理主要用来实现各个微服务实例的自动化注册和发现
1、服务注册
在服务治理框架中,通常会构建一个注册中心,每个服务单元向注册中心等级自己提供的服务,将主机与端口号、版本号、通信协议等一些附加信息告知注册中心,注册中心按服务名分类组织服务清单。
个人的理解:
服务注册就有点公司去工商局备案的感觉,你要开一个公司给别人提供服务,就要服从管理,为了方便管理,大家都要去工商局去备案,工商局定期抽查公司是否续存(注册中心发送心跳),不存在就将备案撤销掉
2、服务发现
服务调用方在调用服务提供方接口的时候,并不知道具体的服务实例位置。因此,调用方需要向服务注册中心咨询服务,并获取所有服务的实例清单,以实现对具体服务实例的访问。
二、Eureka
1、Eureka的使用
单节点模式
- 在pom中引入必要的依赖
<!-- eureka server: 提供服务发现与服务注册 --> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies>
- 在主启动类上添加@EnableEurekaServer注解
@EnableEurekaServer @SpringBootApplication public class EurekaApplication { public static void main(String[] args){ SpringApplication.run(EurekaApplication.class,args); } }
- 在application.yml中配置Eureka
spring: application: name: ad_eureka server: port: 8000 eureka: instance: hostname: localhost client: fetch-registry: false //false表示不需要检索服务 register-with-eureka: false //该应用为注册中心,false代表不向注册中心注册自己 service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
高可用模式
Eureka Server的高可用实际上就是将自己作为服务向其他服务注册中心注册自己,这样就可以形成一组互相注册的服务注册中心,以实现服务清单的互相同步,达到高可用的效果。
spring: application: name: ad_eureka profiles: server1 server: port: 8000 eureka: instance: hostname: server1 prefer-ip-address: false client: service-url: defaultZone: http://server2:8001/eureka/,http://server3:8002/eureka/ --- spring: application: name: ad_eureka profiles: server2 server: port: 8001 eureka: instance: hostname: server2 prefer-ip-address: false client: service-url: defaultZone: http://server1:8000/eureka/,http://server3:8002/eureka/ --- spring: application: name: ad_eureka profiles: server3 server: port: 8002 eureka: instance: hostname: server3 prefer-ip-address: false client: service-url: defaultZone: http://server2:8001/eureka/,http://server1:8000/eureka/
2、Eureka的基本架构
- 服务注册中心:Eureka提供的服务端,提供服务注册与发现的功能
- 服务提供者:提供服务的应用,可以是SpringBoot应用,也可以是其他技术平台且遵循Eureka通信机制的应用。它将自己提供的服务注册到Eureka,以供其他应用发现
- 服务消费者:消费者应用从服务注册中心获取服务列表,从而使消费者可以知道去何处调用其所需要的服务
3、Eureka的集群架构
三、Eureka的单独使用
1、为什么要了解Eureka的单独使用
个人理解,SpringCloud组件之间的相互调用,都是依赖封装好的注解或者类,我们知道其他的组件如何使用注解调用Eureka就好比掌握了少林七十二绝技之一,但是想使用这个绝技,最基础的还是少林罗汉拳(Eureka中的基础组件),罗汉拳就是没有封装过的绝技,但是练到极致也同样牛逼。
2、当前服务如何通过Eureka获取其他服务的信息?
通过DiscoverClient发现其他服务信息
public interface DiscoveryClient { /** * A human readable description of the implementation, used in HealthIndicator * @return the description */ String description(); /** * Get all ServiceInstances associated with a particular serviceId * @param serviceId the serviceId to query * @return a List of ServiceInstance */ //获取与特定serviceId关联的所有ServiceInstances List<ServiceInstance> getInstances(String serviceId); /** * @return all known service ids */ //返回所有已知的服务ID List<String> getServices(); }
可以看到DiscoverClient中的getInstances可以获取到serviceId对应的实例
这里贴一个获取实例的例子
@RequestMapping("/getInstances") public Object getInstances() { List<ServiceInstance> msb_eureka_client = discoveryClient.getInstances("msb_eureka_client"); return msb_eureka_client; }
3、当前服务如何通过Eureka调用其他服务?
通过EurekaClient调用其他服务
@ImplementedBy(DiscoveryClient.class) public interface EurekaClient extends LookupService { // ======================== // getters for InstanceInfo // ======================== public Applications getApplicationsForARegion(@Nullable String region); public Applications getApplications(String serviceUrl); public List<InstanceInfo> getInstancesByVipAddress(String vipAddress, boolean secure); public List<InstanceInfo> getInstancesByVipAddress(String vipAddress, boolean secure, @Nullable String region); public List<InstanceInfo> getInstancesByVipAddressAndAppName(String vipAddress, String appName, boolean secure); // ========================== // getters for local metadata // ========================== public Set<String> getAllKnownRegions(); public InstanceInfo.InstanceStatus getInstanceRemoteStatus(); @Deprecated public List<String> getDiscoveryServiceUrls(String zone); @Deprecated public List<String> getServiceUrlsFromConfig(String instanceZone, boolean preferSameZone); @Deprecated public List<String> getServiceUrlsFromDNS(String instanceZone, boolean preferSameZone); // =========================== // healthcheck related methods // =========================== @Deprecated public void registerHealthCheckCallback(HealthCheckCallback callback); public void registerHealthCheck(HealthCheckHandler healthCheckHandler); public void registerEventListener(EurekaEventListener eventListener); public boolean unregisterEventListener(EurekaEventListener eventListener); public HealthCheckHandler getHealthCheckHandler(); public void shutdown(); public EurekaClientConfig getEurekaClientConfig(); public ApplicationInfoManager getApplicationInfoManager(); }
通过源码我们可以看到,EurekaClient中大致有四种方法:
- 获取实例信息的方法,如getInstancesByVipAddress()
- 获取元数据的方法,如getInstanceRemoteStatus()
- 获取健康状态的方法,如registerHealthCheckCallback()
- 其他方法,如getEurekaClientConfig()
这里放一个通过EurekaClient调用其他方法的例子
使用RestTemplate
@RequestMapping("/useEurekaProviderHi") public Object useEurekaProviderHi() { //获取服务列表 List<InstanceInfo> instancesByVipAddress = eurekaClient.getInstancesByVipAddress("MSB_EUREKA_CLIENT", false); if (instancesByVipAddress.size() > 0) { InstanceInfo instance1 = instancesByVipAddress.get(0); if (instance1.getStatus() == InstanceInfo.InstanceStatus.UP) { String url = "http://" + instance1.getHostName() + ":" + instance1.getPort() + "/getHi"; RestTemplate restTemplate = new RestTemplate(); String responseStr = restTemplate.getForObject(url, String.class); System.out.println(responseStr); } } return "访问成功"; }
这里贴一个写的还挺好的关于Eureka的文章:
https://www.kanzhun.com/mianshiti/592758.html
四、Eureka的自我保护机制与Actuator的使用
1.什么是自我保护机制?
在Eureka的实际应用中,服务可能会受到网络波动或者其他原因的影响,导致服务down掉,此时的Eureka就会触发自我保护机制,维护这些服务不过期,但是如果这个服务直接下线导致在Eureka中找不到实例,可能会触发报错。简而言之,自我保护机制就是给了一些服务犯错的机会,当心跳失败比例在 15 分钟之内低于 85%,便会触发自我保护机制。
2.如何关闭自我保护机制?
在application.properties中配置相应属性即可
eureka.server.enable-self-preservation = false
这里只说简单的使用,暂时不接触底层的原理
3.Actuator的使用
A.导入Jar包
eurekaserver的jar包中自带了actuator,而eurekaclient中没有自带,需要我们自己导入
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
B.配置application.properties
在默认情况下,actuator只开启两个信息节点,我们需要在配置文件中开启相应配置。
//将其他节点暴露出来 management.endpoints.web.exposure.include = "*" //可以通过post请求下线服务 management.endpoint.shutdown.enabled = true
这样的话暴露出来的节点就多了,赞,可以通过访问相应的路径获取对应信息
例如:
通过post请求关闭服务: