一、啥是服务治理

服务治理主要用来实现各个微服务实例的自动化注册和发现

1、服务注册

在服务治理框架中,通常会构建一个注册中心,每个服务单元向注册中心等级自己提供的服务,将主机与端口号、版本号、通信协议等一些附加信息告知注册中心,注册中心按服务名分类组织服务清单。

个人的理解:
服务注册就有点公司去工商局备案的感觉,你要开一个公司给别人提供服务,就要服从管理,为了方便管理,大家都要去工商局去备案,工商局定期抽查公司是否续存(注册中心发送心跳),不存在就将备案撤销掉

2、服务发现

服务调用方在调用服务提供方接口的时候,并不知道具体的服务实例位置。因此,调用方需要向服务注册中心咨询服务,并获取所有服务的实例清单,以实现对具体服务实例的访问。

二、Eureka

图片说明

1、Eureka的使用

单节点模式

  1. 在pom中引入必要的依赖
    <!-- eureka server: 提供服务发现与服务注册 -->
     <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
         </dependency>
     </dependencies>
  2. 在主启动类上添加@EnableEurekaServer注解
    @EnableEurekaServer
    @SpringBootApplication
    public class EurekaApplication {
     public static void main(String[] args){
         SpringApplication.run(EurekaApplication.class,args);
     }
    }
  3. 在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请求关闭服务:
图片说明