Greenwich.SR2版本的Spring Cloud Eureka實例


  作為微服務架構中最為核心和基礎的服務治理,注冊中心提供了微服務實例的自動化注冊與發現。而作為一個服務注冊中心,eureka的作用與傳統的zk、etcd的作用是一樣的,同樣也支持高可用(集群)。不同之處在於它不是作為一個獨立的服務器或者服務器集群存在,而是作為一個組件(或者說服務)存在,它分為服務端組件、客戶端組件。可以把服務端組件看成是zk或者etcd(注冊中心),其他注冊到服務端的組件都可以看成是把客戶端組件,比如服務提供方、消費方的微服務等。另外一個明顯的特征是eureka是由java代碼實現的,因此主要使用對象是JVM兼容的分布式系統。

  搭建單例eureka服務端很簡單,三板斧即可:

  1、pom.xml引入最新版本Greenwich.SR2的spring-cloud-starter-netflix-eureka-server:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>eureka-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

  2、application.properties配置端口、單機的話無需讓注冊中心注冊自己、也無需去注冊中心查詢服務(集群時需要):

#本機端口
server.port=8888

#是否向注冊中心注冊自己
eureka.client.register-with-eureka=false

#是否從注冊中心查詢服務
eureka.client.fetch-registry=false

#注冊中心地址
eureka.client.service-url.defaultZone=http://localhost:8888/eureka/

  3、最后寫一個主類,只要加上@EnableEurekaServer證明它是注冊中心:

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class EurekaServiceApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(EurekaServiceApplication.class, args);
    }
}

  客戶端分服務提供方、服務消費方,先看服務提供方,還是三板斧:

  1、pom需要把eureka客戶端jar引入spring-cloud-starter-netflix-eureka-client:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>eureka-client-service-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

  2、application配置:

#本機端口
server.port=8762
#本機服務名
spring.application.name=a-bootiful-client
#注冊中心地址
eureka.client.service-url.defaultZone=http://localhost:8888/eureka/

  3、主類加上注解@EnableDiscoveryClient用於服務發現:

package hello;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@EnableDiscoveryClient
@SpringBootApplication
public class EurekaClientServiceProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaClientServiceProviderApplication.class, args);
    }
}

@RestController
class ServiceInstanceRestController {

    @Value("${server.port}")
    private String port;

    @Autowired
    private DiscoveryClient discoveryClient;

    @RequestMapping("/service-instances/{applicationName}")
    public List<ServiceInstance> serviceInstancesByApplicationName(
            @PathVariable String applicationName) {
        return this.discoveryClient.getInstances(applicationName);
    }

    @RequestMapping("/hello")
    public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
        return "Hello, " + name + "---------port: " + port;
    }
}

  服務消費方還是老套路:

  1、pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>eureka-client-service-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

  2、application,這里配置了app.service.url是服務方實例名,方便調用時指定,當然你也可以在調用服務提供方的代碼里硬編碼指定:

#本機端口
server.port=8763
#本機服務名
spring.application.name=a-beautiful-client
#注冊中心地址
eureka.client.service-url.defaultZone=http://localhost:8888/eureka/

#服務提供者實例名稱
app.service.url=http://A-BOOTIFUL-CLIENT/

  3、主類同樣需要加上:

package hello;
import hello.service.ConsumerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.ServiceInstance;import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@EnableDiscoveryClient
@SpringBootApplication
public class EurekaClientServiceClientApplication {

    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }


    public static void main(String[] args) {
        SpringApplication.run(EurekaClientServiceClientApplication.class, args);
    }
}


@RestController
class ServiceInstanceRestController {

    @Autowired
    private ConsumerService consumerService;

    @Autowired
    private DiscoveryClient discoveryClient;

    @RequestMapping("/sayHello")
    public String sayHello(@RequestParam(value = "name", defaultValue = "Spring Cloud") String name) {

        return consumerService.call(name);
    }

    @RequestMapping("/service-instances/{applicationName}")
    public List<ServiceInstance> serviceInstancesByApplicationName(
            @PathVariable String applicationName) {
        return this.discoveryClient.getInstances(applicationName);
    }
}

  ConsumerService類:

package hello.service;

public interface ConsumerService {
    String call(String name);

}

  ConusmerServiceImpl類:

package hello.service.impl;

import hello.service.ConsumerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class ConusmerServiceImpl implements ConsumerService {

    @Value("${app.service.url}")
    private String appServiceUrl;

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public String call(String name) {
        ResponseEntity resultResponseEntity = restTemplate.postForEntity(appServiceUrl + "hello?name=" + name, null, String.class);
        if (resultResponseEntity != null && resultResponseEntity.getBody() != null) {
            return name + " says: " + resultResponseEntity.getBody().toString();
        }
        return null;
    }
}

  好了,接下來依次啟動注冊中心、服務提供方、服務消費方,瀏覽器上輸入http://localhost:8763/sayHello?name=world,可以看到消費方通過注冊中心發現了提供方,然后消費方調用了提供方的/hello:

 

  直接調提供方:

  這個是注冊中心:

 

 

 

   如圖,服務端(a-bootiful-client)可以看到有兩個實例,為何起兩個呢?用來測試ribbon的負載均衡,這塊內容詳見Greenwich.SR2版本的Spring Cloud Ribbon實例

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM