SpringCloud——简介,5大组件

1、SpringCloud简介

微服务

微服务化的核心就是将传统的一站式应用,根据业务拆分红一个一个的服务,完全地去解耦合,每个微服务提供单个业务功能也服务,一个服务作一件事,从技术角度看就是一种小而独立的处理过程,相似进程概念,可以自行单独启动或销毀,拥有本身独立的数据库。java

SpringCloud与Dubbo对比

  Dubbo SpringCloud
服务注册中心 Zookeeper Eureka
服务调用方式 RPC RestAPI
服务监控 Dubbo-monitor Spring Boot Admin
断路器 不完善 Hystrix
服务网关 Zuul
分布式配置 Spring Cloud Config
服务跟踪 Spring Cloud Sleuth
消息总线 Spring Cloud Bus
数据流 Spring Cloud Stream
批量任务 Spring Cloud Task

最大区别:SpringCloud抛弃了Dubbo的RPC通讯,采用的是基于HTTP的REST方式 严格来讲,这两种方式各有优劣,虽然从必定程度上来讲,后者牺牲了服务调用的性能,但也避免了上面提到的原生RPC带来的问题。并且REST相比RPC更为灵活,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级别的强依赖,这在强调快速演化的微服务环境下,显得更加合适。python

1、Rest微服务构建

项目结构mysql

microservicecloud  // 父项目
  |- microservicecloud-api  // 存放公共接口、实体类。。
  |- microservicecloud-provider-dept-8081  // 部门服务提供者
  |- microservicecloud-consumer-dept-80  // 部门服务消费者

一、建立maven父项目

书写pom.xml文件web

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <modelVersion>4.0.0</modelVersion>
 6 
 7     <groupId>cn.x5456</groupId>
 8     <artifactId>microservicecloud</artifactId>
 9     <packaging>pom</packaging>
10     <version>1.0-SNAPSHOT</version>
11     <modules>
12         <module>microservicecloud-api</module>
13     </modules>
14 
15     <properties>
16         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
17         <maven.compiler.source>1.8</maven.compiler.source>
18         <maven.compiler.target>1.8</maven.compiler.target>
19         <junit.version>4.12</junit.version>
20         <log4j.version>1.2.17</log4j.version>
21         <lombok.version>1.16.18</lombok.version>
22     </properties>
23 
24     <dependencyManagement>
25         <dependencies>
26             <dependency>
27                 <groupId>org.springframework.cloud</groupId>
28                 <artifactId>spring-cloud-dependencies</artifactId>
29                 <version>Dalston.SR1</version>
30                 <type>pom</type>
31                 <scope>import</scope>
32             </dependency>
33             <dependency>
34                 <groupId>org.springframework.boot</groupId>
35                 <artifactId>spring-boot-dependencies</artifactId>
36                 <version>1.5.9.RELEASE</version>
37                 <type>pom</type>
38                 <scope>import</scope>
39             </dependency>
40             <dependency>
41                 <groupId>mysql</groupId>
42                 <artifactId>mysql-connector-java</artifactId>
43                 <version>5.0.4</version>
44             </dependency>
45             <dependency>
46                 <groupId>com.alibaba</groupId>
47                 <artifactId>druid</artifactId>
48                 <version>1.0.31</version>
49             </dependency>
50             <dependency>
51                 <groupId>org.mybatis.spring.boot</groupId>
52                 <artifactId>mybatis-spring-boot-starter</artifactId>
53                 <version>1.3.0</version>
54             </dependency>
55             <dependency>
56                 <groupId>ch.qos.logback</groupId>
57                 <artifactId>logback-core</artifactId>
58                 <version>1.2.3</version>
59             </dependency>
60             <dependency>
61                 <groupId>junit</groupId>
62                 <artifactId>junit</artifactId>
63                 <version>${junit.version}</version>
64                 <scope>test</scope>
65             </dependency>
66             <dependency>
67                 <groupId>log4j</groupId>
68                 <artifactId>log4j</artifactId>
69                 <version>${log4j.version}</version>
70             </dependency>
71         </dependencies>
72     </dependencyManagement>
73 
74     <build>
75         <finalName>microservicecloud</finalName>
76         <resources>
77             <resource>
78                 <directory>src/main/resources</directory>
79                 <filtering>true</filtering>
80             </resource>
81         </resources>
82         <plugins>
83             <plugin>
84                 <groupId>org.apache.maven.plugins</groupId>
85                 <artifactId>maven-resources-plugin</artifactId>
86                 <configuration>
87                     <delimiters>
88                         <delimit>$</delimit>
89                     </delimiters>
90                 </configuration>
91             </plugin>
92         </plugins>
93     </build>
94 
95 </project>
View Code

二、建立microservicecloud-api项目

和上面同样算法

1)书写pom.xml文件spring

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <parent>
 6         <artifactId>microservicecloud</artifactId>
 7         <groupId>cn.x5456</groupId>
 8         <version>1.0-SNAPSHOT</version>
 9     </parent>
10     <modelVersion>4.0.0</modelVersion>
11 
12     <artifactId>microservicecloud-api</artifactId>
13 
14     <dependencies><!-- 当前Module须要用到的jar包,按本身需求添加,若是父类已经包含了,能够不用写版本号 -->
15         <dependency>
16             <groupId>org.springframework.cloud</groupId>
17             <artifactId>spring-cloud-starter-feign</artifactId>
18         </dependency>
19         <dependency>
20             <groupId>org.springframework.boot</groupId>
21             <artifactId>spring-boot-starter-data-jpa</artifactId>
22         </dependency>
23     </dependencies>
24 </project>
View Code

2)书写实体类sql

// 在api中这样写,有一点问题
@Entity // 告诉JPA这是一个实体类(对应数据表),不是普通的javabean
@Table(name = "tb_dept")   // 不写这个注解,默认为这个类的小写做为名字
public class Dept implements Serializable {

    @Id // 标识这是主键
    @GeneratedValue(strategy = GenerationType.AUTO) // 根据数据库自动选则主键自增类型
    private Long 	deptno; // 主键
    private String 	dname; // 部门名称
    private String 	dbSource;// 来自那个数据库,由于微服务架构能够一个服务对应一个数据库,同一个信息被存储到不一样数据库

三、建立microservicecloudproviderdept8081(提供者)

1)书写pom.xml文件数据库

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <parent>
 6         <artifactId>microservicecloud</artifactId>
 7         <groupId>cn.x5456</groupId>
 8         <version>1.0-SNAPSHOT</version>
 9     </parent>
10     <modelVersion>4.0.0</modelVersion>
11 
12     <artifactId>microservicecloud-provider-dept-8081</artifactId>
13     <dependencies>
14         <!-- 引入本身定义的api通用包,可使用Dept部门Entity -->
15         <dependency>
16             <groupId>cn.x5456</groupId>
17             <artifactId>microservicecloud-api</artifactId>
18             <version>${project.version}</version>
19         </dependency>
20         <!-- actuator监控信息完善 -->
21         <dependency>
22             <groupId>org.springframework.boot</groupId>
23             <artifactId>spring-boot-starter-actuator</artifactId>
24         </dependency>
25         <!-- 将微服务provider侧注册进eureka -->
26         <dependency>
27             <groupId>org.springframework.cloud</groupId>
28             <artifactId>spring-cloud-starter-eureka</artifactId>
29         </dependency>
30         <dependency>
31             <groupId>org.springframework.cloud</groupId>
32             <artifactId>spring-cloud-starter-config</artifactId>
33         </dependency>
34         <dependency>
35             <groupId>junit</groupId>
36             <artifactId>junit</artifactId>
37         </dependency>
38         <!--<dependency>-->
39             <!--<groupId>mysql</groupId>-->
40             <!--<artifactId>mysql-connector-java</artifactId>-->
41         <!--</dependency>-->
42         <dependency>
43             <groupId>com.oracle</groupId>
44             <artifactId>ojdbc14</artifactId>
45             <version>10.2.0.4.0</version>
46         </dependency>
47         <dependency>
48             <groupId>com.alibaba</groupId>
49             <artifactId>druid</artifactId>
50         </dependency>
51         <dependency>
52             <groupId>ch.qos.logback</groupId>
53             <artifactId>logback-core</artifactId>
54         </dependency>
55         <dependency>
56             <groupId>org.mybatis.spring.boot</groupId>
57             <artifactId>mybatis-spring-boot-starter</artifactId>
58         </dependency>
59         <dependency>
60             <groupId>org.springframework.boot</groupId>
61             <artifactId>spring-boot-starter-jetty</artifactId>
62         </dependency>
63         <dependency>
64             <groupId>org.springframework.boot</groupId>
65             <artifactId>spring-boot-starter-web</artifactId>
66         </dependency>
67         <dependency>
68             <groupId>org.springframework.boot</groupId>
69             <artifactId>spring-boot-starter-test</artifactId>
70         </dependency>
71         <!-- 修改后当即生效,热部署 -->
72         <dependency>
73             <groupId>org.springframework</groupId>
74             <artifactId>springloaded</artifactId>
75         </dependency>
76         <dependency>
77             <groupId>org.springframework.boot</groupId>
78             <artifactId>spring-boot-devtools</artifactId>
79         </dependency>
80     </dependencies>
81 
82 </project>
View Code

2)目录结构apache

DeptProvider8081_App编程

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

controller

@RestController
public class DeptController {

	@Autowired
	private DeptService service;

	@RequestMapping(value = "/dept/add", method = RequestMethod.POST)
	public Dept add(Dept dept){

		return service.addDept(dept);
	}

	@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
	public Dept get(@PathVariable("id") Long id)
	{
		return service.findById(id);
	}

	@RequestMapping(value = "/dept/list", method = RequestMethod.GET)
	public List<Dept> list(){
		return service.findAll();
	}

}

service

@Service
public class DeptServiceImpl implements DeptService {

    @Resource
    private DeptRepository deptRepository;


    @Override
    public Dept addDept(Dept dept) {

        return deptRepository.save(dept);
    }

    @Override
    public Dept findById(Long id) {

        return deptRepository.findOne(id);

    }

    @Override
    public List<Dept> findAll() {
        return deptRepository.findAll();
    }
}

repository

public interface DeptRepository extends JpaRepository<Dept,Long> {
}

3)书写配置文件

spring:
  application:
      name: microservicecloud-dept
  datasource:
    url: jdbc:oracle:thin:@127.0.0.1:1521:orcl
    username: scott
    password: tiger
    driver-class-name: oracle.jdbc.OracleDriver
  jpa:
    hibernate:
      # 更新或建立数据表
      ddl-auto: update
    # 控制台打印sql
    show-sql: true
server:
  context-path: /DeptProvider8001_App
  port: 8001

四、建立microservicecloudconsumerdept80

1)书写pom.xml文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <parent>
 6         <artifactId>microservicecloud</artifactId>
 7         <groupId>cn.x5456</groupId>
 8         <version>1.0-SNAPSHOT</version>
 9     </parent>
10     <modelVersion>4.0.0</modelVersion>
11 
12     <artifactId>microservicecloud-consumer-dept-80</artifactId>
13 
14     <dependencies>
15         <dependency><!-- 本身定义的api -->
16             <groupId>cn.x5456</groupId>
17             <artifactId>microservicecloud-api</artifactId>
18             <version>${project.version}</version>
19         </dependency>
20         <!-- Ribbon相关 -->
21         <dependency>
22             <groupId>org.springframework.cloud</groupId>
23             <artifactId>spring-cloud-starter-eureka</artifactId>
24         </dependency>
25         <dependency>
26             <groupId>org.springframework.cloud</groupId>
27             <artifactId>spring-cloud-starter-ribbon</artifactId>
28         </dependency>
29         <dependency>
30             <groupId>org.springframework.cloud</groupId>
31             <artifactId>spring-cloud-starter-config</artifactId>
32         </dependency>
33         <dependency>
34             <groupId>org.springframework.boot</groupId>
35             <artifactId>spring-boot-starter-web</artifactId>
36         </dependency>
37         <!-- 修改后当即生效,热部署 -->
38         <dependency>
39             <groupId>org.springframework</groupId>
40             <artifactId>springloaded</artifactId>
41         </dependency>
42         <dependency>
43             <groupId>org.springframework.boot</groupId>
44             <artifactId>spring-boot-devtools</artifactId>
45         </dependency>
46         <dependency>
47             <groupId>com.oracle</groupId>
48             <artifactId>ojdbc14</artifactId>
49             <version>10.2.0.4.0</version>
50         </dependency>
51     </dependencies>
52 
53 </project>
View Code

2)目录结构

DeptConsumer80_App

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

书写配置类

@Configuration
public class ConfigBean //boot -->spring   applicationContext.xml --- @Configuration配置   ConfigBean = applicationContext.xml{ 
	@Bean
	public RestTemplate getRestTemplate(){
		return new RestTemplate();
	}

}

controller

@RestController
public class DeptController_Consumer{

	private static final String REST_URL_PREFIX = "http://localhost:8001/DeptProvider8001_App";

	/**
	 * 使用 使用restTemplate访问restful接口很是的简单粗暴无脑。 (url, requestMap,
	 * ResponseBean.class)这三个参数分别表明 REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
	 */
	@Autowired
	private RestTemplate restTemplate;

	@RequestMapping(value = "/consumer/dept/add")
	public boolean add(Dept dept)
	{
		return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
	}

	@RequestMapping(value = "/consumer/dept/get/{id}")
	public Dept get(@PathVariable("id") Long id)
	{
		return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);
	}

	@RequestMapping(value = "/consumer/dept/list")
	public List<Dept> list()
	{
		return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);
	}

}

3)配置文件

### 理论上这部分不该该有 ###
spring:
  datasource:
    url: jdbc:oracle:thin:@127.0.0.1:1521:orcl
    username: scott
    password: tiger
    driver-class-name: oracle.jdbc.OracleDriver
  jpa:
    hibernate:
      # 更新或建立数据表
      ddl-auto: update
    # 控制台打印sql
    show-sql: true
################## 
server:
  port: 80
  context-path: /DeptConsumer80_App

2、Eureka

 

简介

 

Eureka是Spring Cloud Netflix的一个子模块,也是核心模块之一。用于云端服务发现,一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。服务的注册与发现对应微服务架构来讲是很是重要的,有了服务的发现与注册,只须要使用服务标识符,就能够访问到服务,而不须要修改服务调用的配置文件了。

 

其功能相似与dubbo的注册中心(zookeeper)。

 

基本架构

 

SpringCloud封装了Netflix公司开发的Eureka模块来实现服务的注册与发现

 

Eureka采用了C-S的设计架构。Eureka Server做为服务注册功能的服务器,它是服务的注册中心。而系统中其余的微服务,使用Eureka的客户端链接到Eureka Server并维持心跳链接,这样系统的维护人员就能够经过Eureka Server来监控系统中各个微服务是否正常运行。SpringCloud的一些其余模块(Zuul)就能够经过Eureka来发现系统中的其余微服务,并执行相关的逻辑。

Eureka包含两个组件:Eureka Server和Eureka Client

 

Eureka Server提供服务注册服务,在各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储全部可用服务节点的信息,服务阶段的信息能够在界面中直观的看到。

 

EurekaClient是一个Java客户端,用于简化EurekaServer的交互,客户端同时也具有一个内置的、使用轮询负载算法的负载均衡器。在应用启动后,将会EurekaServer发送心跳(默认周期是30s)。若是EurekaServer在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中吧这个服务节点移除(默认30s)。

 

SpringCloud中三大角色

 

  • EurekaServer:提供服务的注册和发现

  • Server Provider服务提供方将自身服务注册到Eureka,从而使服务消费方能够找到

  • Service Consumer服务消费方从Eureka获取注册服务列表,从而能够消费服务

Euraka的自我保护模式

 

默认状况下,若是EurekaServer在必定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)。可是当网络分区发生故障时,微服务与EurekaServer之间没法正常通讯,以上行为可能变得很是危险了——由于微服务自己实际上是健康的,此时不该该注销这个微服务。Eureka经过“自我保护模式”来解决这个问题——当EurekaServer节点在短期内丢失过多客户端时(可能网络分区发生故障),那么这个节点就会进入自我保护模式。一旦进入改模式,EurekaServer就会保护服务注册表中的信息,再也不删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,改Eureka节点会自动退出自我保护模式。

综上自我保护模式是一种应对网络异常的安全保护措施。他的架构哲学是宁肯保留全部微服务(无论它健不健康都会保留),也不盲目注销任何微服务。使用自我保护模式,可让Eureka集群更加健壮、稳定。

做为服务注册中心,Eureka比Zookeeper好在哪

分布式系统的CAP理论

● 一致性(C):在分布式系统中的全部数据备份,在同一时刻是否一样的值。(等同于全部节点访问同一份最新的数据副本)

● 可用性(A):在集群中一部分节点故障后,集群总体是否还能响应客户端的读写请求。(对数据更新具有高可用性)

● 分区容错性(P):以实际效果而言,分区至关于对通讯的时限要求。系统若是不能在时限内达成数据一致性,就意味着发生了分区的状况,必须就当前操做在C和A之间作出选择。

Zookeeper保证的是CP

当向注册中心查询服务列表时,咱们能够容忍注册中心返回的是几分钟前的注册信息,但不能接受直接down掉不可用。也就是说,服务注册功能对可用性的要求要高于一致性。可是Zookeeper会出现这样一种状况,当master节点由于网络故障与其余节点失去联系时,剩余节点会从新进行leader选举。问题在于,选举leader的时间太长,30 ~ 120s,且选举期间整个zk集群都是不可用的,这就致使在选举期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大几率会发生的事,虽然服务可以恢复,可是漫长的选举时间致使的注册长期不可用是不能容忍的。

Eureka保证的是AP

Eureka看明白了这一点,所以在设计时就优先保证可用性。Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工做 ,剩余的节点依然能够提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或时若是发现链接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此以外,Eureka还有一种自我保护机制,若是在15分祌内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现如下几种状况:

  1. Eureka再也不从注册列表中移除由于长时间没收到心跳而应该过时的服务

  2. Eureka仍然可以接受新服务的注册和查询请求,可是不会被同步到其它节点上(即保证当前节点依然可用)

  3. 当网络稳定时,当前实例新的注册信息会被同步到其它节点中

所以,Eureka能够很好的应对因网络故障致使部分节点失去联系的状况,而不会像Zookeeper那样是整个注册服务瘫痪。

 

项目中引入Eureka

一、新建Eureka项目microservicecloud-eureka-7001

1)新建项目

2)目录结构

MicroservicecloudEureka7001Application

@SpringBootApplication
@EnableEurekaServer		// 表明eureka服务端
public class MicroservicecloudEureka7001Application {

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

书写配置文件

# 端口号
server.port=7001
# 主机名
eureka.instance.hostname=localhost
# 是否向服务注册中心注册本身
eureka.client.register-with-eureka=false
# 是否检索服务,false表示本身就是注册中心,不须要去检索服务
eureka.client.fetch-registry=false
# 服务注册中心的配置内容,指定服务注册中心的位置
eureka.client.service-url.defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

二、修改提供者和消费者部分配置

1)修改服务提供者与消费者的主方法

@SpringBootApplication
@EnableEurekaClient // eureka客户端
public class DeptProvider8001_App {
public static void main(String[] args) {
SpringApplication.run(DeptProvider8001_App.class, args);
}
}

2)为服务提供者与消费者配置文件中添加配置

eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/

3)还要在restTemplate上添加负载均衡注解,客户端才能够调用

此时url能够改成提供者在Eureka中注册的名字

Eureka集群的搭建

一、再建立2个Eureka项目

二、修改系统hosts文件的映射(为了防止名字冲突)

三、书写配置文件

四、修改服务提供者的配置文件

将这个服务注册到每个eureka上

五、成功页面

3、Ribbon

简介

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具

Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载衡算法,将Netflix的中间层服务链接在一块儿。 Ribbon客户端组件提供一系列完善的配置项如链接超时,重试等。简单的说,就是在配置文件中列出Load Balancer (负载均衡)后面全部的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机链接等)去链接这些机器。咱们也很容易使用Ribbon实现自定义的负载均衡算法。

基本架构

Ribbon在工做时分红两步

第一步先选择EurekaServer,他优先选则在同一个区域内负载较少的server

第二步在根据用户指定的策略,从server渠道的服务注册列表中选则一个地址。

Ribbon的irule组件

Ribbon默认是采用轮询的方式进行负载均衡,咱们可使用irule进行指定。

Ribbon的使用

首先要在(消费者)pom.xml文件中引入jar包

<!-- Ribbon相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>

以前为了可以使用微服务名称来调用服务时,咱们已经使用过ribbon了,没错就是这个:

Robbon默认使用的是轮询算法,总共有如下几种算法:

可使用如下方法进行修改算法

4、Feign

 

简介

 

Feign是一个声明式WebService客户端。使得编写Web服务客户端变得很是容易,咱们只须要建立一个接口,而后在上面添加注解便可

 

Feign旨在使编写JavaHttp客户端变得更容易。前面在使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,造成了一套模板化的调用方法,可是在实际开发中,因为对服务依赖的调用可能不止一处,每每一个接口会被多处调用,因此一般都会针对每一个微服务自行封装一些客户端类来包装这些依赖服努的调用。因此,Feign在此基础上作了进一步封装,由他来帮助咱们定义和实现依赖服务接口的定义。在 Feign的实现下,咱们只需建立一个接口并使用注解的方式来配置它,便可完成对服务提供方的接口绑定,简化了使用Spring cloud Ribbon时,自动封装服务调用客户端的开发量。

 

Feign集成了Ribbon,使用它来进行负载均衡。

 

Feign的使用

一、建立消费者microservicecloud-consumer-dept-feign

pom.xml导入相应依赖

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>

二、在microservicecloud-api中添加接口

@FeignClient(value = "MICROSERVICECLOUD-DEPT/DeptConsumerDeptFeign_App")    // 这个是咱们要调用的提供者在eureka中注册的名字
public interface DeptClientService
{
	@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)  // 要请求 提供者 的url
	public Dept get(@PathVariable("id") long id);

	@RequestMapping(value = "/dept/list", method = RequestMethod.GET)
	public List<Dept> list();

	@RequestMapping(value = "/dept/add", method = RequestMethod.POST)
	public boolean add(Dept dept);
}

三、microservicecloudconsumerdeptfeign中的一些操做

DeptConsumerDeptFeign_App

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages= {"cn.x5456.microservicecloud"})	// 扫描全部Feign的接口
@ComponentScan("cn.x5456.springcloud")	// 扫描咱们调用的controller
public class DeptConsumerDeptFeign_App {
	public static void main(String[] args) {
		SpringApplication.run(DeptConsumerDeptFeign_App.class, args);
	}
}

DeptController_Consumer(变得和咱们面向接口编程同样了)

@RestController
public class DeptController_Consumer {

	@Autowired
	private DeptClientService service;

	@RequestMapping(value = "/consumer/dept/get/{id}")
	public Dept get(@PathVariable("id") Long id)
	{
		return this.service.get(id);
	}

	@RequestMapping(value = "/consumer/dept/list")
	public List<Dept> list()
	{
		return this.service.list();
	}

	@RequestMapping(value = "/consumer/dept/add")
	public Object add(Dept dept)
	{
		return this.service.add(dept);
	}

}

配置文件和之前同样

5、Hystrix(断路器)

简介

Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,好比超时、异常等,Hystrix可以保证在一个依赖出问题的状况下,不会致使总体服务失败,避免级联故障,以提升分布式系统的弹性。 "断路器"自己是一种开关装置,当某个服务单元发生故障以后,经过断路器的故障监控(相似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方没法处理的异常,这样就保证了服务调用方的线程不会被长时间、没必要要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。

服务熔断

一、概念

通常处某个服务故障异常引发,相似现实世界中的“保险丝“,当某个异常条件被触发,直接熔断整个服务,而不是一直等到此服务超时。

二、使用

1)(提供者端)导入依赖

<!-- hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

2)在须要进行熔断处理的方法上添加注解,书写熔断方法

@RestController
public class DeptController {
	@Autowired
	private DeptService service = null;

	@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
	//一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法
	@HystrixCommand(fallbackMethod = "processHystrix_Get")
	public Dept get(@PathVariable("id") Long id) {

		Dept dept = this.service.get(id);
		
		if (null == dept) {
			throw new RuntimeException("该ID:" + id + "没有没有对应的信息");
		}
		
		return dept;
	}

	public Dept processHystrix_Get(@PathVariable("id") Long id) {
		return new Dept().setDeptno(id).setDname("该ID:" + id + "没有没有对应的信息,null--@HystrixCommand")
				.setDb_source("no this database in MySQL");
	}
}

3)在主方法上添加@EnableCircuitBreaker注解

@SpringBootApplication
@EnableEurekaClient //本服务启动后会自动注册进eureka服务中
@EnableCircuitBreaker//对hystrixR熔断机制的支持
public class DeptProvider8001_Hystrix_App
{
	public static void main(String[] args)
	{
		SpringApplication.run(DeptProvider8001_Hystrix_App.class, args);
	}
}

三、问题

  • 没有实现解耦的思想
  • 方法膨胀(每有一个方法就要有一个对应的断路器方法)
  • 服务降级

服务降级

一、概念

降级,通常是从总体负荷考虑。就是当某个服务熔断以后,服务器将再也不被调用,此时客户端能够本身准备一个本地的fallback回调,返回—个缺省值。这样作,虽然服务水平降低,但好歹可用,比直接挂掉要强。

二、使用

1)在microservicecloud-api项目,根据刚刚写的DeptClientService接口新建一个实现了FallbackFactory接口的类DeptClientServiceFallbackFactory

@Component // 不要忘记添加
public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService> {
    @Override
    public DeptClientService create(Throwable throwable) {
        return new DeptClientService() {
            @Override
            public Dept get(long id) {

                Dept dept = new Dept();
                dept.setDname("yyy");

                return dept;
            }

            @Override
            public List<Dept> list() {
                return null;
            }

            @Override
            public boolean add(Dept dept) {
                return false;
            }
        };
    }
}

2)为DeptClientService的注解中添加参数

@FeignClient(value = "MICROSERVICECLOUD-DEPT",fallbackFactory=DeptClientServiceFallbackFactory.class)

3)在消费者端的配置文件中添加下面配置:

feign: 
hystrix:
enabled: true

4)测试

  • 启动enreka,启动提供者,启动消费者
  • 故意关闭服务提供者
  • 再次进行访问,查看效果

6、Zuul(路由网关)

简介

Zuul包含了对请求的路由和过滤两个最主要的功能: 其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础而过滤器功能则负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础。

Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中得到其余微服务的消息,也即之后的访问微服务都是经过Zuul跳转后得到。

相关文章
相关标签/搜索