SpringCloud与Docker微服务架构实战读书笔记(四) - Go语言中文社区

SpringCloud与Docker微服务架构实战读书笔记(四)


Eureka的元数据

Eureka的元数据有两种,分别是标准元数据和自定义元数据。

标准元数据指的是主机名、IP地址、端口号、状态页和健康检查等信息,这些信息都会被发布在服务注册表中,用于服务之间的调用。自定义元数据可以使用eureka.instance.metadata-map配置,这些元数据可以在远程客户端中访问,但一般不会改变客户端的行为,除非客户端知道该元数据的含义。

下面通过一个简单的示例,来更好地理解Eureka的元数据。

改造用户微服务

  1. 复制项目microserver-provider-user,将ArtifactId修改为microserver-provider-user-my-metadata。

  2. 修改application.yml,使用eureka.instance.metadata-map属性为该微服务添加应自定义的元数据:

    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
      instance:
        prefer-ip-address: true
        metadata-map:
          #自定义的元数据,key/value都可以随便写
          my-metadata: 我自定义的元数据
    

改造电影微服务

  1. 复制项目microservice-consumer-movie,将ArtifactId修改为microservice-consumer-movie-understanding-metadata。

  2. 修改Controller。

    package com.itmuch.cloud.study.user.controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.client.ServiceInstance;
    import org.springframework.cloud.client.discovery.DiscoveryClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    import com.itmuch.cloud.study.user.entity.User;
    
    import java.util.List;
    
    @RestController
    public class MovieController {
      @Autowired
      private RestTemplate restTemplate;
    
      @Autowired
      private DiscoveryClient discoveryClient;
    
      @GetMapping("/user/{id}")
      public User findById(@PathVariable Long id) {
        return this.restTemplate.getForObject("http://localhost:8000/" + id, User.class);
      }
    
      /**
       * 查询microservice-provider-user服务的信息并返回
       * @return microservice-provider-user服务的信息
       */
      @GetMapping("/user-instance")
      public List<ServiceInstance> showInfo(){
        return this.discoveryClient.getInstances("microservice-provider-user");
      }
    }
    

    使用DiscoveryClient.getInstances(serviceId),可查询指定微服务在Eureka上的实例列表。

    测试

    1. 启动microservice-discovery-eureka——服务注册组件。

    2. 启动microserver-provider-user-my-metadata——服务提供者。

    3. 启动microservice-consumer-movie-understanding-metadata——服务消费者。

    4. 访问http://localhost:8761/eureka/apps可查看Eureka的metadata。

      This XML file does not appear to have any style information associated with it. The document tree is shown below.
      <?xml version="1.0" encoding="utf-8"?>
      
      <applications> 
        <versions__delta>1</versions__delta>  
        <apps__hashcode>UP_2_</apps__hashcode>  
        <application> 
          <name>MICROSERVICE-CONSUMER-MOVIE</name>  
          <instance> 
            <instanceId>YPThinkPad:microservice-consumer-movie:8010</instanceId>  
            <hostName>192.168.31.58</hostName>  
            <app>MICROSERVICE-CONSUMER-MOVIE</app>  
            <ipAddr>192.168.31.58</ipAddr>  
            <status>UP</status>  
            <overriddenstatus>UNKNOWN</overriddenstatus>  
            <port enabled="true">8010</port>  
            <securePort enabled="false">443</securePort>  
            <countryId>1</countryId>  
            <dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo"> 
              <name>MyOwn</name> 
            </dataCenterInfo>  
            <leaseInfo> 
              <renewalIntervalInSecs>30</renewalIntervalInSecs>  
              <durationInSecs>90</durationInSecs>  
              <registrationTimestamp>1563686373426</registrationTimestamp>  
              <lastRenewalTimestamp>1563693725912</lastRenewalTimestamp>  
              <evictionTimestamp>0</evictionTimestamp>  
              <serviceUpTimestamp>1563685966027</serviceUpTimestamp> 
            </leaseInfo>  
            <metadata class="java.util.Collections$EmptyMap"/>  
            <homePageUrl>http://192.168.31.58:8010/</homePageUrl>  
            <statusPageUrl>http://192.168.31.58:8010/info</statusPageUrl>  
            <healthCheckUrl>http://192.168.31.58:8010/health</healthCheckUrl>  
            <vipAddress>microservice-consumer-movie</vipAddress>  
            <secureVipAddress>microservice-consumer-movie</secureVipAddress>  
            <isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer>  
            <lastUpdatedTimestamp>1563686373426</lastUpdatedTimestamp>  
            <lastDirtyTimestamp>1563686372796</lastDirtyTimestamp>  
            <actionType>ADDED</actionType> 
          </instance> 
        </application>  
        <application> 
          <name>MICROSERVICE-PROVIDER-USER</name>  
          <instance> 
            <instanceId>YPThinkPad:microservice-provider-user:8000</instanceId>  
            <hostName>192.168.31.58</hostName>  
            <app>MICROSERVICE-PROVIDER-USER</app>  
            <ipAddr>192.168.31.58</ipAddr>  
            <status>UP</status>  
            <overriddenstatus>UNKNOWN</overriddenstatus>  
            <port enabled="true">8000</port>  
            <securePort enabled="false">443</securePort>  
            <countryId>1</countryId>  
            <dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo"> 
              <name>MyOwn</name> 
            </dataCenterInfo>  
            <leaseInfo> 
              <renewalIntervalInSecs>30</renewalIntervalInSecs>  
              <durationInSecs>90</durationInSecs>  
              <registrationTimestamp>1563685921736</registrationTimestamp>  
              <lastRenewalTimestamp>1563693723982</lastRenewalTimestamp>  
              <evictionTimestamp>0</evictionTimestamp>  
              <serviceUpTimestamp>1563685921035</serviceUpTimestamp> 
            </leaseInfo>  
            <metadata> 
              <my-metadata>我自定义的元数据</my-metadata> 
            </metadata>  
            <homePageUrl>http://192.168.31.58:8000/</homePageUrl>  
            <statusPageUrl>http://192.168.31.58:8000/info</statusPageUrl>  
            <healthCheckUrl>http://192.168.31.58:8000/health</healthCheckUrl>  
            <vipAddress>microservice-provider-user</vipAddress>  
            <secureVipAddress>microservice-provider-user</secureVipAddress>  
            <isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer>  
            <lastUpdatedTimestamp>1563685921736</lastUpdatedTimestamp>  
            <lastDirtyTimestamp>1563685920502</lastDirtyTimestamp>  
            <actionType>ADDED</actionType> 
          </instance> 
        </application> 
      </applications>
      
    5. 访问http://localhost:8010/user-instance,可以返回类似如下的内容。

      [{
      	host: "192.168.31.58",
      	port: 8000,
      	metadata: {
      		my - metadata: "我自定义的元数据"
      	},
      	secure: false,
      	uri: "http://192.168.31.58:8000",
      	instanceInfo: {
      		instanceId: "YPThinkPad:microservice-provider-user:8000",
      		app: "MICROSERVICE-PROVIDER-USER",
      		appGroupName: null,
      		ipAddr: "192.168.31.58",
      		sid: "na",
      		homePageUrl: "http://192.168.31.58:8000/",
      		statusPageUrl: "http://192.168.31.58:8000/info",
      		healthCheckUrl: "http://192.168.31.58:8000/health",
      		secureHealthCheckUrl: null,
      		vipAddress: "microservice-provider-user",
      		secureVipAddress: "microservice-provider-user",
      		countryId: 1,
      		dataCenterInfo: {
      			@class: "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo",
      			name: "MyOwn"
      		},
      		hostName: "192.168.31.58",
      		status: "UP",
      		leaseInfo: {
      			renewalIntervalInSecs: 30,
      			durationInSecs: 90,
      			registrationTimestamp: 1563685921736,
      			lastRenewalTimestamp: 1563686401290,
      			evictionTimestamp: 0,
      			serviceUpTimestamp: 1563685921035
      		},
      		isCoordinatingDiscoveryServer: false,
      		metadata: {
      			my - metadata: "我自定义的元数据"
      		},
      		lastUpdatedTimestamp: 1563685921736,
      		lastDirtyTimestamp: 1563685920502,
      		actionType: "ADDED",
      		asgName: null,
      		overriddenStatus: "UNKNOWN"
      	},
      	serviceId: "MICROSERVICE-PROVIDER-USER"
      }]
      

      可以看到,使用DiscoveryClient的API获得了用户微服务的各种信息,其中包括标准元数据和自定义元数据。例如IP、端口等信息都是标准元数据,用于服务之间的调用;同时,自定义的元数据my-metadata,也可通过客户端查询到,但是并不会改变客户端的行为。

    Eureka Server的REST端点

    Eureka Server提供了一些REST端点。非JVM的微服务可使用这些REST端点操作Eureka,从而实现注册与发现。事实上,前文所讲的Eureka Client就是一个使用Java写的、操作这些REST端点的类库。也可分析这些REST端点,编写其他语言的Eureka Client。

    下表是Eureka提供的REST端点,可以使用XML或者JSON与这些端点通信,默认是XML。

    请求名称 请求方式 HTTP地址 请求描述
    注册新服务 POST /eureka/apps/{appID} 传递JSON或者XML格式参数内容,HTTP code为204时表示成功
    取消注册服务 DELETE /eureka/apps/{appID}/{instanceID} HTTP code为200时表示成功
    发送服务心跳 PUT /eureka/apps/{appID}/{instanceID} HTTP code为200时表示成功
    查询所有服务 GET /eureka/apps HTTP code为200时表示成功,返回XML/JSON数据内容
    查询指定appID的服务列表 GET /eureka/apps/{appID} HTTP code为200时表示成功,返回XML/JSON数据内容
    查询指定appID&instanceID GET /eureka/apps/{appID}/{instanceID} 获取指定appID以及InstanceId的服务信息,HTTP code为200时表示成功,返回XML/JSON数据内容
    查询指定instanceID服务列表 GET /eureka/apps/instances/{instanceID} 获取指定instanceID的服务列表,HTTP code为200时表示成功,返回XML/JSON数据内容
    变更服务状态 PUT /eureka/apps/{appID}/{instanceID}/status?value=DOWN 服务上线、服务下线等状态变动,HTTP code为200时表示成功
    变更元数据 PUT /eureka/apps/{appID}/{instanceID}/metadata?key=value HTTP code为200时表示成功
    查询指定IP下的服务列表 GET /eureka/vips/{vipAddress} HTTP code为200时表示成功
    查询指定安全IP下的服务列表 GET /eureka/svips/{svipAddress} HTTP code为200时表示成功

在上面列表中参数解释:

  • {appID}:服务名称,对应spring.application.name参数值
  • {instanceID}:实例名称,如果已经自定义instanceId则对应eureka.instance.instance-id参数值。在AWS环境中,instanceID表示微服务实例ID,在非AWS环境则表示实例的主机名。

示例

注册微服务到Eureka Server上

Eureka Client启动成功后会发送POST方式的请求到/eureka/apps/{appID},发送注册请求时的主体内容在官网也有介绍,如果我们根据指定的主体内容发送请求到Eureka Server时也是可以将服务注册成功的,主体内容要以XML/JSON格式的XSD传递:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xsd:element name="instance">
        <xsd:complexType>
            <xsd:all>
                <!-- hostName in ec2 should be the public dns name, within ec2 public dns name will
                     always resolve to its private IP -->
                <xsd:element name="hostName" type="xsd:string" />
                <xsd:element name="app" type="xsd:string" />
                <xsd:element name="ipAddr" type="xsd:string" />
                <xsd:element name="vipAddress" type="xsd:string" />
                <xsd:element name="secureVipAddress" type="xsd:string" />
                <xsd:element name="status" type="statusType" />
                <xsd:element name="port" type="xsd:positiveInteger" minOccurs="0" />
                <xsd:element name="securePort" type="xsd:positiveInteger" />
                <xsd:element name="homePageUrl" type="xsd:string" />
                <xsd:element name="statusPageUrl" type="xsd:string" />
                <xsd:element name="healthCheckUrl" type="xsd:string" />
               <xsd:element ref="dataCenterInfo" minOccurs="1" maxOccurs="1" />
                <!-- optional -->
                <xsd:element ref="leaseInfo" minOccurs="0"/>
                <!-- optional app specific metadata -->
                <xsd:element name="metadata" type="appMetadataType" minOccurs="0" />
            </xsd:all>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="dataCenterInfo">
        <xsd:complexType>
             <xsd:all>
                 <xsd:element name="name" type="dcNameType" />
                 <!-- metadata is only required if name is Amazon -->
                 <xsd:element name="metadata" type="amazonMetdataType" minOccurs="0"/>
             </xsd:all>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="leaseInfo">
        <xsd:complexType>
            <xsd:all>
                <!-- (optional) if you want to change the length of lease - default if 90 secs -->
                <xsd:element name="evictionDurationInSecs" minOccurs="0"  type="xsd:positiveInteger"/>
            </xsd:all>
        </xsd:complexType>
    </xsd:element>

    <xsd:simpleType name="dcNameType">
        <!-- Restricting the values to a set of value using 'enumeration' -->
        <xsd:restriction base = "xsd:string">
            <xsd:enumeration value = "MyOwn"/>
            <xsd:enumeration value = "Amazon"/>
        </xsd:restriction>
    </xsd:simpleType>

    <xsd:simpleType name="statusType">
        <!-- Restricting the values to a set of value using 'enumeration' -->
        <xsd:restriction base = "xsd:string">
            <xsd:enumeration value = "UP"/>
            <xsd:enumeration value = "DOWN"/>
            <xsd:enumeration value = "STARTING"/>
            <xsd:enumeration value = "OUT_OF_SERVICE"/>
            <xsd:enumeration value = "UNKNOWN"/>
        </xsd:restriction>
    </xsd:simpleType>

    <xsd:complexType name="amazonMetdataType">
        <!-- From <a class="jive-link-external-small" href="http://docs.amazonwebservices.com/AWSEC2/latest/DeveloperGuide/index.html?AESDG-chapter-instancedata.html" target="_blank">http://docs.amazonwebservices.com/AWSEC2/latest/DeveloperGuide/index.html?AESDG-chapter-instancedata.html</a> -->
        <xsd:all>
            <xsd:element name="ami-launch-index" type="xsd:string" />
            <xsd:element name=
                            
                            版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/yphust/article/details/96744885
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢