Spring Cloud微服务: 服务注册发现Eureka,服务调用Feign,熔断器Hystrix

1.Spring Cloud简介

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。

Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装,屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

2.Spring Cloud使用示例

工具列表:IDEA、Maven

项目构成:服务注册中心、服务提供者、服务消费者。

项目结构如下:

image

2.1.创建空白工程

为了方便管理,我们创建一个空白工程,我们例子中的3个项目都作为这个空白工程的子模块创建。

主要步骤如下:

1.File->New->Project,选择Maven

image

2.点击Next,输入相关信息

image

3.创建完成后把其它文件都删掉,只保留pom.xml即可。

2.2.服务注册发现模块

此模块对应项目结构中的demo-eureka

主要步骤如下:

1.在主工程上File->New->Module,选择Spring Initializr

image

2.点击Next,输入模块信息

image

3.点击Next,选择Cloud Discovery->Eureka Server

image

4.生成的pom文件部分配置

<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>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
</dependencies>
</dependencyManagement>

5.启动类,加上@EnableEurekaServer注解

@SpringBootApplication
@EnableEurekaServer
public class DemoEurekaApplication {

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

6.配置文件application.properties添加如下配置

# 端口号
server.port=8000
# 关闭自我保护
eureka.server.enable-self-preservation=false
# 清理服务器时间间隔[5s]
eureka.server.eviction-interval-timer-in-ms=5000
# 主机名
eureka.instance.hostname=localhost
# 是否将自己作为客户端注册到Eureka Server[当前模块只是作为Eureka Server服务端所以设为false]
eureka.client.register-with-eureka=false
# 是否从Eureka Server获取注册信息[当前是单点的Eureka Server所以不需要同步其它节点的数据]
eureka.client.fetch-registry=false
# Eureka Server[查询注册服务]地址
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka

2.3.服务提供者模块

此模块对应项目结构中的demo-provider

1.创建过程不再赘述,与创建服务注册发现模块的区别是,依赖中选择:

  • Web->Web
  • Cloud Discovery->Eureka Server

2.pom文件依赖配置如下

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

<dependencyManagement>
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
</dependencies>
</dependencyManagement>

3.启动类,加上@EnableDiscoveryClient,表示其作为服务发现客户端

@SpringBootApplication
@EnableDiscoveryClient
public class DemoProviderApplication {

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

}

4.application.properties添加如下配置

# 端口号
server.port=8010
# 应用名称
spring.application.name=provider
# Eureka Server服务器地址
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/

5.定义MyController类

@RestController
public class MyController {

    @RequestMapping(value = "/info", method = RequestMethod.GET)
    public String getDefaultInfo() {
        try {
            //休眠2秒,测试超时服务熔断[直接关闭服务提供者亦可]
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return "Hello provider";
    }

    @RequestMapping(value = "/info/{name}", method = RequestMethod.POST)
    public String getInfo(@PathVariable String name) {
        return "Hello " + name;
    }

}

2.3.服务消费者模块

此模块对应项目结构中的demo-consumer

1.创建过程不再赘述,与创建服务注册发现模块的区别是,依赖中选择:

  • Web->Web
  • Cloud Discovery->Eureka Server
  • Cloud Routing->Feign

2.pom文件依赖配置如下

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <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-openfeign</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>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
</dependencies>
</dependencyManagement>

3.启动类,加上@EnableFeignClients和@EnableEurekaClient

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class DemoConsumerApplication {

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

}

4.application.properties添加如下配置

# 端口号
server.port=8020
# 应用名称
spring.application.name=consumer
# Eureka Server服务器地址
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
# 高版本spring-cloud-openfeign请求分为两层,先ribbon控制,后hystrix控制.
# Ribbon请求连接的超时时间
ribbon.ConnectionTimeout=5000
# Ribbon请求处理的超时时间.
ribbon.ReadTimeout=5000
# 设置服务熔断超时时间[默认1s]
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000
# 开启hystrix以支持服务熔断[高版本默认false关闭],如果置为false,则请求超时交给ribbon控制.
# feign.hystrix.enabled=true

5.定义服务接口类InfoClient,作为调用远程服务的本地入口

/**
 * FeignClient配置说明
 * 1.name:被调用的服务应用名称
 * 2.fallback: InfoFallBack作为熔断实现,当请求provider失败时调用其中的方法
 * 3.configuration: feign配置
 */
@FeignClient(name = "provider", fallback = InfoFallBack.class, configuration = MyFeignConfig.class)
public interface InfoClient {

    @RequestMapping(value = "/info", method = RequestMethod.GET)
    String getDefaultInfo();

    @RequestMapping(value = "/info/{name}", method = RequestMethod.POST)
    String getInfo(@PathVariable("name") String name);

}

6.定义熔断类InfoFallBack,如果远程服务无法成功请求,则调用指定的本地逻辑方法

@Component
public class InfoFallBack implements InfoClient {

    @Override
    public String getDefaultInfo() {
        return "fallback info";
    }

    @Override
    public String getInfo(String name) {
        return "fallback default info";
    }

}

7.定义feign配置类MyFeignConfig

@Configuration
public class MyFeignConfig {

    /**
     * Feign打印日志等级
     *
     * @return
     */
    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }

}

注意这里的Logger用的是feign下面的,需要引入

import feign.Logger;

8.定义服务调用类ConsumerController,通过本地方法入口调用远程服务

@RestController
public class ConsumerController {

    @Autowired
    private InfoClient infoClient;

    @RequestMapping(value = "/call/info", method = RequestMethod.GET)
    public String consumerInfo(){
        return infoClient.getDefaultInfo();
    }

    @RequestMapping(value = "/call/info/{name}", method = RequestMethod.GET)
    public String consumerInfo(@PathVariable String name){
        return infoClient.getInfo(name);
    }
}

2.4.测试

1.依次启动demo-eureka、demo-provider、demo-consumer
2.访问http://127.0.0.1:8000/
你会看到我们的提供者、消费者都已经注册


image.png

3.访问消费者

image.png
image.png

4.测试服务熔断,application.properties配置修改如下

# 设置服务熔断超时时间[默认1s]
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=1000
# 开启hystrix以支持服务熔断[高版本默认false关闭],如果置为false,则请求超时交给ribbon控制.
feign.hystrix.enabled=true
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,928评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,192评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,468评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,186评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,295评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,374评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,403评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,186评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,610评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,906评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,075评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,755评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,393评论 3 320
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,079评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,313评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,934评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,963评论 2 351

推荐阅读更多精彩内容