Spring Cloud學(xué)習-Eureka印机、Ribbon和Feign

Talk is cheap,show me the code 门驾, 書上得來終覺淺射赛,絕知此事要躬行。在自己真正實現(xiàn)的過程中奶是,會遇到很多莫名其妙的問題楣责,而正是在解決這些問題的過程中,你會發(fā)現(xiàn)自己之前思維的盲點聂沙。

引子

看完《微服務(wù)設(shè)計》后秆麸,算是補上了自己在服務(wù)化這塊的理論知識,在業(yè)界及汉,一般有兩種微服務(wù)的實踐方法:基于dubbo的微服務(wù)架構(gòu)沮趣、基于Spring Cloud的微服務(wù)架構(gòu)。從概念上來講坷随,Dubbo和Spring Cloud并不能放在一起對比房铭,因為Dubbo僅僅是一個RPC框架,實現(xiàn)Java程序的遠程調(diào)用温眉,實施服務(wù)化的中間件則需要自己開發(fā)缸匪;而Spring Cloud則是實施微服務(wù)的一系列套件,包括:服務(wù)注冊與發(fā)現(xiàn)类溢、斷路器凌蔬、服務(wù)狀態(tài)監(jiān)控、配置管理闯冷、智能路由砂心、一次性令牌、全局鎖蛇耀、分布式會話管理计贰、集群狀態(tài)管理等。

在有贊蒂窒,我們基于Dubbo實施服務(wù)化躁倒,剛開始是基于ZooKeeper進行服務(wù)注冊與發(fā)現(xiàn),現(xiàn)在已經(jīng)轉(zhuǎn)成使用Etcd洒琢。我這次學(xué)習Spring Cloud秧秉,則是想成體系得學(xué)習下微服務(wù)架構(gòu)的實現(xiàn),也許能夠?qū)贒ubbo實施微服務(wù)架構(gòu)有所借鑒衰抑。

Spring Cloud下有很多工程:

  • Spring Cloud Config:依靠git倉庫實現(xiàn)的中心化配置管理象迎。配置資源可以映射到Spring的不同開發(fā)環(huán)境中,但是也可以使用在非Spring應(yīng)用中。
  • Spring Cloud Netflix:不同的Netflix OSS組件的集合:Eureka砾淌、Hystrix啦撮、Zuul、Archaius等汪厨。
  • Spring Cloud Bus:事件總線赃春,利用分布式消息將多個服務(wù)連接起來。非常適合在集群中傳播狀態(tài)的改變事件(例如:配置變更事件)
  • Spring Cloud Consul:服務(wù)發(fā)現(xiàn)和配置管理劫乱,由Hashicorp團隊開發(fā)织中。

我決定先從Spring Cloud Netflix看起,它提供了如下的功能特性:

  • 服務(wù)發(fā)現(xiàn):Eureka-server實例作為服務(wù)提供者衷戈,可以注冊到服務(wù)注冊中心狭吼,Eureka客戶端可以通過Spring管理的bean發(fā)現(xiàn)實例;
  • 服務(wù)發(fā)現(xiàn):嵌套式的Eureka服務(wù)可以通過聲明式的Java配置文件創(chuàng)建殖妇;
  • 斷路器:利用注解刁笙,可以創(chuàng)建一個簡單的Hystrix客戶端;
  • 斷路器:通過Java配置文件可以創(chuàng)建內(nèi)嵌的Hystrix控制面板谦趣;
  • 聲明式REST客戶端:使用Feign可以創(chuàng)建聲明式采盒、模板化的HTTP客戶端;
  • 客戶端負載均衡器:Ribbon
  • 路由器和過濾器:Zuul可以在微服務(wù)架構(gòu)中提供路由功能蔚润、身份驗證磅氨、服務(wù)遷移、金絲雀發(fā)布等功能嫡纠。

本文計劃利用Eureka實現(xiàn)一個簡答的服務(wù)注冊于發(fā)現(xiàn)的例子烦租,需要創(chuàng)建三個角色:服務(wù)注冊中心、服務(wù)提供者除盏、服務(wù)消費者叉橱。

實踐

1. 服務(wù)注冊中心

在IDEA中創(chuàng)建一個Spring Cloud工程,引入Eureka-Server包者蠕,pom文件整體如下:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example.springcloud</groupId>
    <artifactId>service-register</artifactId>
    <version>1.0-SNAPSHOT</version>


    <!-- spring boot的parent 配置文件窃祝,有大部分spring boot需要用的Jar包 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
    </parent>

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

    <!-- spring boot的maven打包插件 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

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

        <!-- spring boot test-->
        <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>Camden.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

在src/main/java包下創(chuàng)建一個名為hello的包,然后創(chuàng)建EurekaServiceRegisterApplication類踱侣,并用@EnableEurekaServer和@SpringBootApplication兩個注解修飾粪小,后者是Spring Boot應(yīng)用都需要用的,這里不作過多解釋抡句;@EnableEurekaServer注解的作用是觸發(fā)Spring Boot的自動配置機制探膊,由于我們之前在pom文件中導(dǎo)入了eureka-server,spring boot會在容器中創(chuàng)建對應(yīng)的bean待榔。EurekaServiceRegisterApplication的代碼如下:

package hello;

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

/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2017/3/2
 * Time: 20:02
 */

@EnableEurekaServer //通過@EnableEurekaServer啟動一個服務(wù)注冊中心給其他應(yīng)用使用
@SpringBootApplication
public class EurekaServiceRegisterApplication {

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

在application.properties中還需要增加如下配置逞壁,才能創(chuàng)建一個真正可以使用的服務(wù)注冊中心。

#注冊服務(wù)的端口號
server.port=8761

#是否需要注冊到注冊中心,因為該項目本身作為服務(wù)注冊中心腌闯,所以為false
eureka.client.register-with-eureka=false
#是否需要從注冊中心獲取服務(wù)列表绳瘟,原因同上,為false
eureka.client.fetch-registry=false
#注冊服務(wù)器的地址:服務(wù)提供者和服務(wù)消費者都要依賴這個地址
eureka.client.service-url.defaultZone=http://localhost:${server.port}/eureka

logging.level.com.netflix.eureka=OFF
logging.level.com.netflix.discovery=OFF

啟動注冊服務(wù)姿骏,并訪問:http://localhost:8761糖声,就可以看到如下界面。

服務(wù)注冊中心后臺

2. 服務(wù)提供者

創(chuàng)建一個Spring Boot工程工腋,代表服務(wù)提供者,該服務(wù)提供者會暴露一個加法服務(wù)畅卓,接受客戶端傳來的加數(shù)和被加數(shù)擅腰,并返回兩者的和。

工程的pom文件內(nèi)容如下:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example.springcloud</groupId>
    <artifactId>service-client</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
        <relativePath/> 
    </parent>

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

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

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</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-eureka-server</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Camden.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

其中的關(guān)鍵在于spring-cloud-starter-eureka這個Jar包翁潘,其中包含了eureka的客戶端實現(xiàn)趁冈。

在src/main/java/hello下創(chuàng)建工程的主類EurekaServerProducerApplication,使用@EnableDiscoveryClient注解修飾拜马,該注解在服務(wù)啟動的時候渗勘,可以觸發(fā)服務(wù)注冊的過程,向配置文件中指定的服務(wù)注冊中心(Eureka-Server)的地址注冊自己提供的服務(wù)俩莽。EurekaServerProducerApplication的源碼如下:

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2017/3/2
 * Time: 20:34
 */
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaServerProducerApplication {

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

}

配置文件的內(nèi)容如下:

#服務(wù)提供者的名字
spring.application.name=compute-service

#服務(wù)提供者的端口號
server.port=8888

#服務(wù)注冊中心的地址
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/

服務(wù)提供者的基本框架搭好后旺坠,需要實現(xiàn)服務(wù)的具體內(nèi)容,在ServiceInstanceRestController類中實現(xiàn)扮超,它的具體代碼如下:

package hello;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2017/3/2
 * Time: 20:36
 */
@RestController
public class ServiceInstanceRestController {

    private static final Logger logger = LoggerFactory.getLogger(ServiceInstanceRestController.class);

    @Autowired
    private DiscoveryClient discoveryClient; //服務(wù)發(fā)現(xiàn)客戶端

    @GetMapping(value = "/add")
    public Integer add(@RequestParam Integer a, @RequestParam Integer b) {
        ServiceInstance instance = discoveryClient.getLocalServiceInstance();
        Integer r = a + b;
        logger.info("/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + ", result:" + r);
        return r;
    }
}

先啟動服務(wù)注冊中心的工程取刃,然后再啟動服務(wù)提供者,在訪問:localhost:8761出刷,如下圖所示璧疗,服務(wù)提供者已經(jīng)注冊到服務(wù)注冊中心啦。

服務(wù)提供者注冊到服務(wù)注冊中心

在Spring Cloud Netflix中馁龟,使用Ribbon實現(xiàn)客戶端負載均衡崩侠,使用Feign實現(xiàn)聲明式HTTP客戶端調(diào)用——即寫得像本地函數(shù)調(diào)用一樣。

3. 服務(wù)消費者-Ribbon

創(chuàng)建一個Spring boot工程坷檩,引入ribbon和eureka却音,pom文件內(nèi)容如下:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example.springcloud</groupId>
    <artifactId>serviceconsumer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
    </parent>

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

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

    <dependencies>
        <!-- 客戶端負載均衡 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>

        <!-- eureka客戶端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>

        <!-- spring boot實現(xiàn)Java Web服務(wù)-->
        <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>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Camden.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

創(chuàng)建EurekaConsumerApplication類,定義REST客戶端實例矢炼,代碼如下:

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2017/3/2
 * Time: 22:55
 */
@EnableDiscoveryClient //開啟服務(wù)發(fā)現(xiàn)的能力
@SpringBootApplication
public class EurekaConsumerApplication {

    @Bean //定義REST客戶端僧家,RestTemplate實例
    @LoadBalanced //開啟負債均衡的能力
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

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

application.properties中定義了服務(wù)注冊中心的地址、消費者服務(wù)的端口號裸删、消費者服務(wù)的名稱這些內(nèi)容:

#應(yīng)用名稱
spring.application.name=ribbon-consumer

#端口號
server.port=9000

#注冊中心的地址
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/

消費者服務(wù)的入口為:ConsumerController八拱,我們通過這個實例進行測試。消費者服務(wù)啟動過程中,會從服務(wù)注冊中心中拉最新的服務(wù)列表肌稻,當瀏覽器觸發(fā)對應(yīng)的請求清蚀,就會根據(jù)COMPUTE-SERVICE查找服務(wù)提供者的IP和端口號,然后發(fā)起調(diào)用爹谭。

package hello;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2017/3/2
 * Time: 22:58
 */
@RestController
public class ConsumerController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping(value = "/add")
    public String add() {
        return restTemplate.getForEntity("http://COMPUTE-SERVICE/add?a=10&b=20", String.class).getBody();
    }
}

首先啟動服務(wù)注冊中心枷邪,第二分別啟動兩個服務(wù)提供者(IP相同、端口不同即可)诺凡,然后啟動服務(wù)消費者东揣。


兩個服務(wù)提供者

在瀏覽器里訪問localhost:9000/add兩次,可以看到請求有時候會在8888端口的服務(wù)腹泌,有時候會到8889的服務(wù)嘶卧。具體背后選擇的原理,還有待后續(xù)研究凉袱。

4. 服務(wù)消費者-Feign

上一節(jié)中芥吟,使用類似restTemplate.getForEntity("http://COMPUTE-SERVICE/add?a=10&b=20", String.class).getBody()這樣的語句進行服務(wù)間調(diào)用并非不可以,只是我們在服務(wù)化的過程中专甩,希望跨服務(wù)調(diào)用能夠看起來像本地調(diào)用钟鸵,這也是我理解的Feign的使用場景。

創(chuàng)建一個spring boot工程涤躲,該工程的pom文件與上一節(jié)的類似棺耍,只是把ribbon的依賴換為feign的即可,代碼如下:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example.springcloud</groupId>
    <artifactId>serviceconsumer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
    </parent>

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

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

    <dependencies>
        <!-- Feign實現(xiàn)聲明式HTTP客戶端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>

        <!-- eureka客戶端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>

        <!-- spring boot實現(xiàn)Java Web服務(wù)-->
        <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>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Camden.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

首先創(chuàng)建應(yīng)用程序啟動類:EurekaConsumerApplication种樱,代碼如下:

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;


/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2017/3/19
 * Time: 16:59
 */
@EnableDiscoveryClient //用于啟動服務(wù)發(fā)現(xiàn)功能
@EnableFeignClients //用于啟動Fegin功能
@SpringBootApplication
public class EurekaConsumerApplication {

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

然后定義遠程調(diào)用的接口烈掠,在hello包下創(chuàng)建depend包,然后創(chuàng)建ComputeClient接口缸托,使用@FeignClient("COMPUTE-SERVICE")注解修飾左敌,COMPUTE-SERVICE就是服務(wù)提供者的名稱,然后定義要使用的服務(wù)俐镐,代碼如下:

package hello.depend;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2017/3/19
 * Time: 17:02
 */
@FeignClient("COMPUTE-SERVICE")
public interface ComputeClient {

    @RequestMapping(method = RequestMethod.GET, value = "/add")
    Integer add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b);
}

在ConsumerController中矫限,像引入普通的spring bean一樣引入ComputeClient對象,其他的和Ribbon的類似佩抹。

package hello;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import hello.depend.ComputeClient;

/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2017/3/19
 * Time: 17:06
 */
@RestController
public class ConsumerController {

    @Autowired
    private ComputeClient computeClient;

    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public Integer add() {
        return computeClient.add(10, 20);
    }
}

application.properties的內(nèi)容如下:

#應(yīng)用名稱
spring.application.name=fegin-consumer

#端口號
server.port=9000

#注冊中心的地址
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/

啟動fegin消費者叼风,訪問localhost:9000/add,也可以看到服務(wù)提供者已經(jīng)收到了消費者發(fā)來的請求棍苹。

請求到達服務(wù)提供者1
請求到達服務(wù)提供者2

源碼下載

  1. 服務(wù)注冊中心(Eureka服務(wù)端)
  2. 服務(wù)提供者(Eureka客戶端)
  3. 服務(wù)消費者-Ribbon(Eureka客戶端)
  4. 服務(wù)消費者-Feign(Eureka客戶端)

參考資料

  1. Spring Cloud構(gòu)建微服務(wù)架構(gòu)(一)服務(wù)注冊與發(fā)現(xiàn)
  2. Spring Cloud實現(xiàn)服務(wù)注冊于發(fā)現(xiàn)
  3. spring-cloud-netflix官網(wǎng)
  4. spring cloud 官網(wǎng)
  5. 使用Spring Cloud Feign作為HTTP客戶端調(diào)用遠程HTTP服務(wù)

本號專注于后端技術(shù)无宿、JVM問題排查和優(yōu)化、Java面試題枢里、個人成長和自我管理等主題孽鸡,為讀者提供一線開發(fā)者的工作和成長經(jīng)驗蹂午,期待你能在這里有所收獲。


javaadu
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末彬碱,一起剝皮案震驚了整個濱河市豆胸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌巷疼,老刑警劉巖晚胡,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嚼沿,居然都是意外死亡估盘,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門骡尽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來遣妥,“玉大人,你說我怎么就攤上這事爆阶≡锿福” “怎么了沙咏?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵辨图,是天一觀的道長。 經(jīng)常有香客問我肢藐,道長故河,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上闪盔,老公的妹妹穿的比我還像新娘上陕。我一直安慰自己,他們只是感情好范删,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般宙橱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蘸拔,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天师郑,我揣著相機與錄音,去河邊找鬼调窍。 笑死宝冕,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的邓萨。 我是一名探鬼主播地梨,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼菊卷,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了湿刽?” 一聲冷哼從身側(cè)響起的烁,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎诈闺,沒想到半個月后渴庆,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡雅镊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年襟雷,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仁烹。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡耸弄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出卓缰,到底是詐尸還是另有隱情计呈,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布征唬,位于F島的核電站捌显,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏总寒。R本人自食惡果不足惜扶歪,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望摄闸。 院中可真熱鬧善镰,春花似錦、人聲如沸年枕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽熏兄。三九已至品洛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間霍弹,已是汗流浹背毫别。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留典格,地道東北人岛宦。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像耍缴,于是被迫代替她去往敵國和親砾肺。 傳聞我的和親對象是個殘疾皇子挽霉,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)变汪,斷路器侠坎,智...
    卡卡羅2017閱讀 134,601評論 18 139
  • 1 為什么需要服務(wù)發(fā)現(xiàn) 簡單來說,服務(wù)化的核心就是將傳統(tǒng)的一站式應(yīng)用根據(jù)業(yè)務(wù)拆分成一個一個的服務(wù)裙盾,而微服務(wù)在這個基...
    謙小易閱讀 25,076評論 4 93
  • Spring Cloud學(xué)習02-服務(wù)注冊與發(fā)現(xiàn) Spring Cloud簡介 Spring Cloud是一個基于...
    it_zzy閱讀 4,617評論 2 20
  • 軟件是有生命的实胸,你做出來的架構(gòu)決定了這個軟件它這一生是坎坷還是幸福。 本文不是講解如何使用Spring Cloud...
    Bobby0322閱讀 22,610評論 3 166
  • 生活在北方的我早已適應(yīng)了這里四季分明的氣候 看著滿大街金黃色的樹葉就知道已經(jīng)進入深秋了 秋天是一個讓人悲涼的季節(jié)番官,...
    趙皮囊閱讀 220評論 0 0