SpringCloud微服务搭建详解 - Go语言中文社区

SpringCloud微服务搭建详解


具体关于SpringCloud介绍请参考其他文章,下面主要讲解SpringCloud搭建微服务的步骤,其中用到了Eurake、Ribbon、Feign、Hystrix、Zuul、Config技术。
本次案例主要分为以下几个微服务

  • 提供者服务用于操作user表,进行增删改查;
  • 消费者服务用于请求提供者服务,进行增删改查;
  • 公共模块微服务,用于提供其他微服务共同需要的功能;

本次案例用的工具版本如下
eclipse : Mars
JDK : 1.8
SpringCloud : Dalston
SpringBoot : 1.5.9

一、建立一个总工程

首先建立一个microservice-parent总工程,总工程中并不做什么业务逻辑,总工程主要定义一个POM文件,将后续各个微服公用的一些jar包在总工程的pom中进行导入。为方便起见,建立一个working set用于归类所有的微服务,命名为springcloudset。然后建立总工程
New -> Maven -> Maven Project
在这里插入图片描述
注意,Packaging模式要选择pom模式,不要选择jar模式。
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>com.lzj.springcloud</groupId>
	<artifactId>microservice-parent</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>pom</packaging>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<junit.version>4.12</junit.version>
		<log4j.version>1.2.17</log4j.version>
		<lombok.version>1.16.18</lombok.version>
	</properties>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Dalston.SR1</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
			<dependency>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-dependencies</artifactId>
				<version>1.5.9.RELEASE</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
			<dependency>
			    <groupId>mysql</groupId>
			    <artifactId>mysql-connector-java</artifactId>
			    <version>5.1.46</version>
			</dependency>
			<dependency>
			    <groupId>com.alibaba</groupId>
			    <artifactId>druid</artifactId>
			    <version>1.1.0</version>
			</dependency>
			<dependency>
				<groupId>org.mybatis.spring.boot</groupId>
				<artifactId>mybatis-spring-boot-starter</artifactId>
				<version>1.3.0</version>
			</dependency>
			<dependency>
				<groupId>ch.qos.logback</groupId>
				<artifactId>logback-core</artifactId>
				<version>1.2.3</version>
			</dependency>
			<dependency>
				<groupId>junit</groupId>
				<artifactId>junit</artifactId>
				<version>${junit.version}</version>
				<scope>test</scope>
			</dependency>
			<dependency>
				<groupId>log4j</groupId>
				<artifactId>log4j</artifactId>
				<version>${log4j.version}</version>
			</dependency>
		</dependencies>
	</dependencyManagement>
</project>

二、建立公共微服

然后建立一个microservice-com的公共模块,用于提供后续微服需要的公共的东西。创建好公共模块,其它微服务需要的话,不用再创建,直接引用该模块即可。
1、下面在总工程下,即microservice-parent下创建第一个微服务microservice-com模块。
New -> Maven -> Maven Module
这里写图片描述

这里写图片描述
注意,Packaging不要选择pom模式,而应该选择ja模式,后续的微服都是如此。
pom.xml内容为:

<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>
	<!-- 继承父工程 -->
	<parent>
		<groupId>com.lzj.springcloud</groupId>
		<artifactId>microservice-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<!-- 当前工程的名字 -->
	<artifactId>microservice-com</artifactId>
	<dependencies><!-- 当前Module需要用到的jar包,按自己需求添加,如果父类已经包含了,可以不用写版本号 -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>
	</dependencies>
</project>

2、然后在该模块中建立一个User的bean,以供其它微服务进行调用。

package com.lzj.springcloud.entity;
public class User {
	private int id;
	private String name;
	private int age;
	
	public User() {
		super();
	}

	public User(int id, String name, int age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
	
}

3、创建完公共微服后,执行mvn clean install进行装载。
创建完microservice-com模块后,在microservice-parent父工程中的pom.xml文件中增加了

	<modules>
		<module>microservice-com</module>
	</modules>

microservice-com工程目录如下;
这里写图片描述
三、建立microservice-provider微服务

1、与建立microservice-com服务类似,建立一个microservice-provider微服务
2、该服务用于提供直接操作数据库user表。首先在pom中配置依赖的包,操作数据库需要的数据库驱动、数据源等。

<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>
	<parent>
		<groupId>com.lzj.springcloud</groupId>
		<artifactId>microservice-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>

	<artifactId>microservice-provider</artifactId>

	<dependencies>
		<dependency>
			<groupId>com.lzj.springcloud</groupId>
			<artifactId>microservice-com</artifactId>
			<version>${project.version}</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-core</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jetty</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>
		</dependency>
		<!-- 修改后立即生效,热部署 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>springloaded</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>
	</dependencies>

</project>

在microservice-provider微服找那个需要引用microservice-com微服中User bean,所以在pom文件中引入了microservice-com的依赖。

		<dependency>
			<groupId>com.lzj.springcloud</groupId>
			<artifactId>microservice-com</artifactId>
			<version>${project.version}</version>
		</dependency>

3、在microservice-provider需要操作数据库,在application.yml中配置mybatis和数据源如下:

server: 
  port: 8002

mybatis: 
  config-location: "classpath:mybatis/mybatis.cfg.xml"        # mybatis配置文件所在路径
  mapper-locations: 
    - "classpath:mybatis/mapper/**/*.xml"                     # mapper映射文件
  type-aliases-package: com.lzj.springcloud.entity            # 别名类所在包

spring: 
  application: 
    name: microservicecloud-provider                          #微服务的名字
  datasource: 
    driver-class-name: org.gjt.mm.mysql.Driver                # mysql驱动包      
    type: com.alibaba.druid.pool.DruidDataSource              # 当前数据源操作类型
    url: "jdbc:mysql://localhost:3306/lzj"                    # 数据库名称
    username: root
    password: lzjlzj
    dbcp2: 
      initial-size: 5                                         # 初始化连接数
      max-total: 5                                            # 最大连接数
      max-wait-millis: 200                                    # 等待连接获取的最大超时时间
      min-idle: 5                                             # 数据库连接池的最小维持连接数

4、在src/main/resources目录下创建mybatis文件夹后新建mybatis.cfg.xml文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

	<!-- 开启二级缓存 -->
	<settings> 
    	<setting name="cacheEnabled" value="true"/>  
	</settings> 

</configuration>

5、创建Dao接口,用于操作user表的接口

package com.lzj.springcloud.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.lzj.springcloud.entity.User;

@Mapper
public interface UserDao {

	public boolean addUser(User user);
	
	public User getUser(int id);
	
	public List<User> getUsers();
}

6、在src/main/resources/mybatis目录下创建mapper目录,并在mapper目录下创建UserMapper.xml文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lzj.springcloud.dao.UserDao">

    <select id="getUser" resultType="User" parameterType="int">
        select * from user where ID=#{id}
    </select>
    
    <select id="getUsers" resultType="User">
    	select * from user
    </select>
    
    <insert id="addUser" parameterType="User">
    	insert into user(NAME, AGE) values(#{name}, #{age})
    </insert>
    
</mapper>

7、创建UserService服务接口

package com.lzj.springcloud.service;
import java.util.List;
import com.lzj.springcloud.entity.User;
public interface UserService {
	
	public boolean addUser(User user);
	
	public User getUser(int id);
	
	public List<User> getUsers();
}

8、创建UserServiceImpl接口的实现

package com.lzj.springcloud.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.lzj.springcloud.dao.UserDao;
import com.lzj.springcloud.entity.User;
import com.lzj.springcloud.service.UserService;

@Service
public class UserServiceImpl implements UserService {

	@Autowired
	private UserDao userDao;
	
	@Override
	public boolean addUser(User user) {
		boolean flag;
		flag = userDao.addUser(user);
		return flag;
	}

	@Override
	public User getUser(int id) {
		User user = userDao.getUser(id);
		return user;
	}

	@Override
	public List<User> getUsers() {
		List<User> users = userDao.getUsers();
		return users;
	}

}

9、创建Controller层,用于相应REST请求

package com.lzj.springcloud.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.lzj.springcloud.entity.User;
import com.lzj.springcloud.service.UserService;

@RestController
public class UserController {

	@Autowired
	private UserService service;
	
	@RequestMapping(value="/add", method=RequestMethod.POST)
	public boolean addUser(@RequestBody User user){
		boolean flag = service.addUser(user);
		return flag;
	}
	
	@RequestMapping(value="/get/{id}", method=RequestMethod.GET)
	public User getUser(@PathVariable("id") int id){
		User user = service.getUser(id);
		return user;
	}
	
	@RequestMapping(value="/getUser/list", method=RequestMethod.GET)
	public List<User> getUsers(){
		List<User> users = service.getUsers();
		return users;
	}
}

10、创建microservice-provider的启动类

package com.lzj.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ProviderApplication {

	public static void main(String[] args) {

		SpringApplication.run(ProviderApplication.class, args);
	}

}

11、测试microservice-provider微服
启动microservice-provider服务,然后在浏览器中发送请求
http://localhost:8002/getUser/list,相应结果如下
这里写图片描述
创建并配置完microservice-provider后,在microservice-parent的pom的文件中,module标签如下

	<modules>
		<module>microservice-com</module>
		<module>microservice-provider</module>
		<module>microservice-consumer</module>
	</modules>

microservice-provider工程目录如下
这里写图片描述

四、建立microservice-consumer微服务

microservice-consumer服务用于请求microservice-provicer
创建与microservice-com类似,在microservice-parent下创建microservice-consumer微服。
1、pom配置如下:

<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>
  <parent>
    <groupId>com.lzj.springcloud</groupId>
    <artifactId>microservice-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>microservice-consumer</artifactId>
  
	<dependencies>
		<!-- 依赖microservice-com模块 -->
		<dependency>
			<groupId>com.lzj.springcloud</groupId>
			<artifactId>microservice-com</artifactId>
			<version>${project.version}</version>
		</dependency>
				<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- 修改后立即生效,热部署 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>springloaded</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>
	</dependencies>
</project>

热部署即为,工程每次修改完后,会重新部署。

2、application.yml配置文件如下:
配置访问端口

server: 
  port: 8003

3、配置RestTemplate的bean
RestTemplate用于模拟发送REST的客户端请求

package com.lzj.springcloud.configbean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ConfigBean {
	
	@Bean
	public RestTemplate getRestTemplate(){
		return new RestTemplate();
	}
}

3、配置controller层

package com.lzj.springcloud.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.lzj.springcloud.entity.User;

@RestController
public class UserConsumerController {
	private static String REST_URL_PREFIX = "http://localhost:8002";
	
	@Autowired
	private RestTemplate restTemplate;
	
	@RequestMapping(value="/consumer/add")
	public boolean addUser(User user){
		Boolean flag = restTemplate.postForObject(REST_URL_PREFIX + "/add", user, Boolean.class);
		return flag;
	}
	
	@RequestMapping(value="/consumer/get/{id}")
	public User get(@PathVariable("id") int id){
		User user = restTemplate.getForObject(REST_URL_PREFIX + "/get" + "/id", User.class);
		return user;
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@RequestMapping(value="/consumer/list")
	public List<User> getList(){
		List list = restTemplate.getForObject(REST_URL_PREFIX + "/getUser/list", List.class);
		return list;
	}
}

4、创建启动类

package com.lzj.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ConsumerApplication {

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

}

5、测试
在浏览器中发送
http://localhost:8003/consumer/add?name=lzj5&age=35
相应如下:
这里写图片描述

发送请求后,在数据库user表中插入了一条数据
这里写图片描述
至此需要的微服务已经全部创建完毕,在microservice-parent的pom文件中可以看到总工程下有三个微服务。

 	<modules>
		<module>microservice-com</module>
		<module>microservice-provider</module>
		<module>microservice-consumer</module>
	</modules>

五、建立microservice-eurake1微服务

eureka微服务用于注册和发现服务。
首先建立一个依赖于microservice-parent的microservice-eurake1工程,与上面建立方法一样。
1、pom文件配置如下:

<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>
	<parent>
		<groupId>com.lzj.springcloud</groupId>
		<artifactId>microservice-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	
	<artifactId>microservice-eurake1</artifactId>
  
	<dependencies>
		<!--eureka-server服务端 -->
		<dependency>
    		<groupId>org.springframework.cloud</groupId>
    		<artifactId>spring-cloud-netflix-eureka-server</artifactId>
		</dependency>
		<!-- 修改后立即生效,热部署 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>springloaded</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>
	</dependencies>
  
</project>

如果出现“Failed to read artifact descriptor for org.springframework.cloud:spring-cloud-st”问题,请参考解决“Failed to read artifact descriptor for org.springframework.cloud:spring-cloud-st”

2、application.yml文件配置如下

eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      
server:
  port: 9001

3、创建启动类

package com.lzj.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {

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

}

注意,一定不要忘记@EnableEurekaServer注解,该注解用于激活eureka的服务端。
现在可以启动microservice-eureka微服务了
这里写图片描述
正确创建eureka微服务后,启动页面如上图所示,只是还没有微服务注册进来。

5、把microservice-provider微服务注册进microservice-eureka服务中

  • 在microservice-provider微服务中的pom文件加入下面依赖
		<!-- 将微服务microservice-provider侧注册进eureka -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-config</artifactId>
		</dependency>		

microservice-provider中的pom文件如下:

<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>
	<parent>
		<groupId>com.lzj.springcloud</groupId>
		<artifactId>microservice-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>

	<artifactId>microservice-provider</artifactId>

	<dependencies>
		<dependency>
			<groupId>com.lzj.springcloud</groupId>
			<artifactId>microservice-com</artifactId>
			<version>${project.version}</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-core</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jetty</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>
		</dependency>
		<!-- 将微服务microservice-provider侧注册进eureka -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-config</artifactId>
		</dependency>		
		<!-- 修改后立即生效,热部署 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>springloaded</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>
	</dependencies>

</project>
  • 在microservice-provider微服务中的application.yml文件中加入如下配置
    表示把microservice-provider微服务注册进http://localhost:9001/eureka指示的服务中,即microservice-eureka微服务中。
 eureka:
  client:
    service-url:
      defaultZone: http://localhost:9001/eureka

microservice-provider中application.yml配置文件如下:

server: 
  port: 8002

mybatis: 
  config-location: "classpath:mybatis/mybatis.cfg.xml"        # mybatis配置文件所在路径
  mapper-locations: 
    - "classpath:mybatis/mapper/**/*.xml"                     # mapper映射文件
  type-aliases-package: com.lzj.springcloud.entity            # 别名类所在包


spring: 
  application: 
    name: microservicecloud-provider                          #微服务的名字
  datasource: 
    driver-class-name: org.gjt.mm.mysql.Driver                # mysql驱动包      
    type: com.alibaba.druid.pool.DruidDataSource              # 当前数据源操作类型
    url: "jdbc:mysql://localhost:3306/lzj"                    # 数据库名称
    username: root
    password: lzjlzj
    dbcp2: 
      initial-size: 5                                         # 初始化连接数
      max-total: 5                                            # 最大连接数
      max-wait-millis: 200                                    # 等待连接获取的最大超时时间
      min-idle: 5                                             # 数据库连接池的最小维持连接数

eureka:
  client:
    service-url:
      defaultZone: http://localhost:9001/eureka
  • 在microservice-provider微服务中的启动类上加入@EnableEurekaClient注解。表示microservice-provider微服务启动时就启动eureka的客户端,该客户端自动的把microservice-provider服务注册进microservice-eureka1中。
package com.lzj.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient  //本服务启动后会自动注册进eureka服务中
public class ProviderApplication {

	public static void main(String[] args) {

		SpringApplication.run(ProviderApplication.class, args);
	}

}

6、测试microservice-provider服务已经注册进了microservice-eureka1服务。
启动microservice-eureka1微服务,然后再启动microservice-provider微服务,
在浏览器中请求http://localhost:9001/,反馈网页如下:
这里写图片描述
可见网页中Application那一栏多了一个MICROSERVICECLOUD-PROVIDER服务,此处显示的服务名字是在microservice-provider服务中的application.yml文件中配置的

spring: 
  application: 
    name: microservicecloud-provider                          #微服务的名字

为追求完美者,下面完善注册服务的信息,如果只是想达到功能,7、8、9可以不用看。
7、修改注册服务的主机名称
我们看到在上述的测试中,注册进eureka中的MICROSERVICE-PROVIDER服务,在状态一栏里面显示的是主机名称:服务名称的形式,主机默认是我本人主机名称,如下图所示。
这里写图片描述

下面修改microservicecloud-provider中的application.yml文件,关于eureka的部分改为如下:

eureka:
  client:
    service-url:
      defaultZone: http://localhost:9001/eureka
  instance:
    instance-id: microservicecloud-provider8002

重启服务,状态栏中显示的即为配置的instance-id名称。

对应关系如下
这里写图片描述

8、eureka中显示注册微服务的ip信息
当鼠标放在注册微服务的链接上,左下角显示注册微服务的ip信息,如下所示
这里写图片描述
左下角显示了microservice-provider微服务的ip信息,要想达到此效果,只需要microservice-provider服务中application.yml中eureka的配置改为如下

eureka:
  client:
    service-url:
      defaultZone: http://localhost:9001/eureka
  instance:
    instance-id: microservicecloud-provider8002               #自定义服务名称信息
    prefer-ip-address: true                                   #访问路径可以显示IP地址

9、点击注册微服务链接,显示微服务的info信息
这里写图片描述
当点击上图划红线的链接处,显示下面erro信息
这里写图片描述
下面定制当点击链接时,显示指定信息
首先在microservice-parent的pom中增加<build>的配置,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>com.lzj.springcloud</groupId>
	<artifactId>microservice-parent</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>pom</packaging>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<junit.version>4.12</junit.version>
		<log4j.version>1.2.17</log4j.version>
		<lombok.version>1.16.18</lombok.version>
	</properties>


	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Dalston.SR1</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
			<dependency>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-dependencies</artifactId>
				<version>1.5.9.RELEASE</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
			<dependency>
			    <groupId>mysql</groupId>
			    <artifactId>mysql-connector-java</artifactId>
			    <version>5.1.46</version>
			</dependency>
			<dependency>
			    <groupId>com.alibaba</groupId>
			    <artifactId>druid</artifactId>
			    <version>1.1.0</version>
			</dependency>
			<dependency>
				<groupId>org.mybatis.spring.boot</groupId>
				<artifactId>mybatis-spring-boot-starter</artifactId>
				<version>1.3.0</version>
			</dependency>
			<dependency>
				<groupId>ch.qos.logback</groupId>
				<artifactId>logback-core</artifactId>
				<version>1.2.3</version>
			</dependency>
			<dependency>
				<groupId>junit</groupId>
				<artifactId>junit</artifactId>
				<version>${junit.version}</version>
				<scope>test</scope>
			</dependency>
			<dependency>
				<groupId>log4j</groupId>
				<artifactId>log4j</artifactId>
				<version>${log4j.version}</version>
			</dependency>
		</dependencies>
	</dependencyManagement>
	
	<build>
		<finalName>microservicecloud</finalName>
		<resources>
			<resource>
				<directory>src/main/resources</directory>
				<filtering>true</filtering>
			</resource>
		</resources>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-resources-plugin</artifactId>
				<configuration>
					<delimiters>
						<delimit>$</delimit>
					</delimiters>
				</configuration>
			</plugin>
		</plugins>
	</build>	
	
	<modules>
		<module>microservice-com</module>
		<module>microservice-provider</module>
		<module>microservice-consumer</module>
		<module>microservice-eurake1</module>
	</modules>
</project>

然后再microservice-provider的服务中增加如下依赖

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>	

最后在microservice-provider中application.yml中配置显示的info信息

server: 
  port: 8002

mybatis: 
  config-location: "classpath:mybatis/mybatis.cfg.xml"        # mybatis配置文件所在路径
  mapper-locations: 
    - "classpath:mybatis/mapper/**/*.xml"                     # mapper映射文件
  type-aliases-package: com.lzj.springcloud.entity            # 别名类所在包


spring: 
  application: 
    name: microservicecloud-provider                          #微服务的名字
  datasource: 
    driver-class-name: org.gjt.mm.mysql.Driver                # mysql驱动包      
    type: com.alibaba.druid.pool.DruidDataSource              # 当前数据源操作类型
    url: "jdbc:mysql://localhost:3306/lzj"                    # 数据库名称
    username: root
    password: lzjlzj
    dbcp2: 
      initial-size: 5                                         # 初始化连接数
      max-total: 5                                            # 最大连接数
      max-wait-millis: 200                                    # 等待连接获取的最大超时时间
      min-idle: 5                                             # 数据库连接池的最小维持连接数

eureka:
  client:
    service-url:
      defaultZone: http://localhost:9001/eureka
  instance:
    instance-id: microservicecloud-provider8002               #自定义服务名称信息
    prefer-ip-address: true                                   #访问路径可以显示IP地址
    
info: 
  app.name: microservicecloud-provider
  company.name: www.lzj.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$

重启microservice-eurake1和microservicecloud-provider微服务,点击注册的微服务microservicecloud-provider的链接,显示如下页面
这里写图片描述

10、eureka的自我保护
过段时间,微服务没有用时,会出现下面红色的警告信息,即为eureka的自我保护。
这里写图片描述

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

在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例。当它收到的心跳数重新恢复到阈值以上时,该Eureka Server节点就会自动退出自我保护模式。它的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。

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

在Spring Cloud中,可以使用eureka.server.enable-self-preservation = false 禁用自我保护模式。

六、建立eureka集群

第五步只是建立了一个eureka的微服务,如果当这个微服务down掉了,那么其它微服务就不能被注册和发现,整个系统就会down掉,所以下面建立多个eureka微服务,配置eureka集群,需要注册的微服务要注册到所有的eureka的微服务中,即注册到整个集群上,当一个eureka的微服务挂掉了,其它的eureka微服可以继续工作。
首先修改host文件,添加127.0.0.1的多个域名映射,方便后面模拟根据多个地址进行注册服务。
分别复制microservice-eurake1工程为microservice-eurake2和microservice-eurake3,
把microservice-eurake2服务中pom文件中的artifactId改为(因为之前该微服是复制过来的,如果是创建过来的就不用修改)<artifactId>microservice-eurake2</artifactId>
把microservice-eurake3服务中pom文件中的artifactId改为<artifactId>microservice-eurake3</artifactId>
修改microservice-eureka1的application.yml文件为

 eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/        #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。
      defaultZone: http://eureka9003.com:9003/eureka/,http://eureka9002.com:9002/eureka/
server:
  port: 9001

修改microservice-eureka2的application.yml文件为

eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      defaultZone: http://eureka9001.com:9001/eureka/,http://eureka9003.com:9003/eureka/
server:
  port: 9002

修改microservice-eureka3的application.yml文件为

eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      defaultZone: http://eureka9001.com:9001/eureka/,http://eureka9002.com:9002/eureka/
      
server:
  port: 9003

然后修改microservice-provider微服务application.yml中的defaultZone配置,把该微服务同时注册到三个eureka微服务中,即eureka集群中。

server: 
  port: 8002

mybatis: 
  config-location: "classpath:mybatis/mybatis.cfg.xml"        # mybatis配置文件所在路径
  mapper-locations: 
    - "classpath:mybatis/mapper/**/*.xml"                     # mapper映射文件
  type-aliases-package: com.lzj.springcloud.entity            # 别名类所在包


spring: 
  application: 
    name: microservicecloud-provider                          #微服务的名字
  datasource: 
    driver-class-name: org.gjt.mm.mysql.Driver                # mysql驱动包      
    type: com.alibaba.druid.pool.DruidDataSource              # 当前数据源操作类型
    url: "jdbc:mysql://localhost:3306/lzj"                    # 数据库名称
    username: root
    password: lzjlzj
    dbcp2: 
      initial-size: 5                                         # 初始化连接数
      max-total: 5                                            # 最大连接数
      max-wait-millis: 200                                    # 等待连接获取的最大超时时间
      min-idle: 5                                             # 数据库连接池的最小维持连接数

eureka:
  client:
    service-url:
      #defaultZone: http://localhost:9001/eureka
      defaultZone: http://eureka9001.com:9001/eureka/,http://eureka9002.com:9002/eureka/,http://eureka9003.com:9003/eureka/
  instance:
    instance-id: microservicecloud-provider8002               #自定义服务名称信息
    prefer-ip-address: true                                   #访问路径可以显示IP地址
    
info: 
  app.name: microservicecloud-provider
  company.name: www.lzj.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$

测试:运行microservice-eurake1、microservice-eurake2、microservice-eurake3、microservice-provider
从浏览器中访问eureka1的管理端http://localhost:9001/
这里写图片描述
可以看出,两个划横线的为microservice-eurake1的备份,microservice-provider为注册上来的服务。eureka的3个微服务组成了一个服务注册的集群,只有有一个能工作,能保证业务的执行。

七、Ribbon负载均衡

Ribbon的负载均衡是应用于客户端的,即调用一方的,在本案例中就是应用于microservice-consumer微服务的,下面就对microservice-consumer微服务使用负载均衡。
1、microservice-consumer进行Ribbon配置
下面进行修改microservice-consumer微服务的配置
pom文件中增加Ribbon需要的依赖

		<!-- 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>

修改application.yml文件,增加eureka的服务注册功能,修改后的配置如下

server: 
  port: 8003

eureka:
  client:
    register-with-eureka: false
    service-url: 
      defaultZone: http://eureka9003.com:9003/eureka/,http://eureka9002.com:9002/eureka/,http://eureka9001.com:9001/eureka/

负载均衡实际是根据RestTemplate根据均衡算法进行调度不同地址上的同一个微服务的部署。所以修改ConfigBean,在RestTemplate上加@LoadBalanced注解。

@Configuration
public class ConfigBean {
	
	@Bean
	@LoadBalanced
	public RestTemplate getRestTemplate(){
		return new RestTemplate();
	}
}

把microservice-consumer也注册到eureka服务中,需要在启动类上加@EnableEurekaClient注解

@SpringBootApplication
@EnableEurekaClient
public class ConsumerApplication {

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

}

修改controller层,不再通过地址和端口调取其它微服的应用,而是根据微服务的名来调取应用。修改后如下

@RestController
public class UserConsumerController {
//	private static String REST_URL_PREFIX = "http://localhost:8002";
	/*直接根据微服务名调用,而不再是根据地址和端口了,运用了eureka的发现功能*/
	private static String REST_URL_PREFIX = "http://microservicecloud-provider";
	
	@Autowired
	private RestTemplate restTemplate;
	
	@RequestMapping(value="/consumer/add")
	public boolean addUser(User user){
		Boolean flag = restTemplate.postForObject(REST_URL_PREFIX + "/add", user, Boolean.class);
		return flag;
	}
	
	@RequestMapping(value="/consumer/get/{id}")
	public User get(@PathVariable("id") int id){
		User user = restTemplate.getForObject(REST_URL_PREFIX + "/get/" + id, User.class);
		return user;
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@RequestMapping(value="/consumer/list")
	public List<User> getList(){
		List list = restTemplate.getForObject(REST_URL_PREFIX + "/getUser/list", List.class);
		return list;
	}
}

只是修改了private static String REST_URL_PREFIX = “http://microservicecloud-provider”;

测试:修改上述配置后,下面进行测试,启动microservice-eurake1、microservice-eurake2、microservice-eurake3微服务,然后启动microservice-provider提供者微服务,最后启动带Ribbon负载均衡配置的消费者(客户端)微服务microservice-consumer。从浏览器中发送请求http://localhost:8003/consumer/list,响应页面如下
这里写图片描述

说明可以从消费端通过微服务名找到提供者微服务,然后进行调用。

2、Ribbon负载均衡
上面在消费端microservice-consumer配置好了Ribbon,提供者微服务目前只有一个。为减小提供者微服务的压力,现在再部署两个提供者微服务,当客户端发送请求时,由三个微服务中的一个随机的响应请求。
复制microservice-provider工程生成microservice-provider2和microservice-provider3
修改microservice-provider2的启动类为ProviderApplication2
修改microservice-provider3的启动类为ProviderApplication3
修改microservice-provider2的application.yml配置为

server: 
  port: 8003

mybatis: 
  config-location: "classpath:mybatis/mybatis.cfg.xml"        # mybatis配置文件所在路径
  mapper-locations: 
    - "classpath:mybatis/mapper/**/*.xml"                     # mapper映射文件
  type-aliases-package: com.lzj.springcloud.entity            # 别名类所在包


spring: 
  application: 
    name: microservicecloud-provider                          #微服务的名字
  datasource: 
    driver-class-name: org.gjt.mm.mysql.Driver                # mysql驱动包      
    type: com.alibaba.druid.pool.DruidDataSource              # 当前数据源操作类型
    url: "jdbc:mysql://localhost:3306/lzj"                    # 数据库名称
    username: root
    password: lzjlzj
    dbcp2: 
      initial-size: 5                                         # 初始化连接数
      max-total: 5                                            # 最大连接数
      max-wait-millis: 200                                    # 等待连接获取的最大超时时间
      min-idle: 5                                             # 数据库连接池的最小维持连接数

eureka:
  client:
    service-url:
      #defaultZone: http://localhost:9001/eureka
      defaultZone: http://eureka9001.com:9001/eureka/,http://eureka9002.com:9002/eureka/,http://eureka9003.com:9003/eureka/
  instance:
    instance-id: microservicecloud-provider8003               #自定义服务名称信息
    prefer-ip-address: true                                   #访问路径可以显示IP地址
    
info: 
  app.name: microservicecloud-provider
  company.name: www.lzj.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$

修改microservice-provider3的配置为

server: 
  port: 8004

mybatis: 
  config-location: "classpath:mybatis/mybatis.cfg.xml"        # mybatis配置文件所在路径
  mapper-locations: 
    - "classpath:mybatis/mapper/**/*.xml"                     # mapper映射文件
  type-aliases-package: com.lzj.springcloud.entity            # 别名类所在包


spring: 
  application: 
    name: microservicecloud-provider                          #微服务的名字
  datasource: 
    driver-class-name: org.gjt.mm.mysql.Driver                # mysql驱动包      
    type: com.alibaba.druid.pool.DruidDataSource              # 当前数据源操作类型
    url: "jdbc:mysql://localhost:3306/lzj"                    # 数据库名称
    username: root
    password: lzjlzj
    dbcp2: 
      initial-size: 5                                         # 初始化连接数
      max-total: 5                                            # 最大连接数
      max-wait-millis: 200                                    # 等待连接获取的最大超时时间
      min-idle: 5                                             # 数据库连接池的最小维持连接数

eureka:
  client:
    service-url:
      #defaultZone: http://localhost:9001/eureka
      defaultZone: http://eureka9001.com:9001/eureka/,http://eureka9002.com:9002/eureka/,http://eureka9003.com:9003/eureka/
  instance:
    instance-id: microservicecloud-provider8004               #自定义服务名称信息
    prefer-ip-address: true                                   #访问路径可以显示IP地址
    
info: 
  app.name: microservicecloud-provider
  company.name: www.lzj.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$

只是分别修改了server.port和eureka.instance.instance-id。

为方便观察哪一个提供者微服务响应的客户端请求,在提供者微服中分别打印两条日志,
microservice-provider微服务中UserServiceImpl类中getUser方法修改为如下:

	@Override
	public User getUser(int id) {
		User user = userDao.getUser(id);
		System.out.println("microservice-provider微服务在响应客户端请求……");
		System.out.println("user : " + user);
		return user;
	}

microservice-provider2微服务中UserServiceImpl类中getUser方法修改为如下:

	@Override
	public User getUser(int id) {
		User user = userDao.getUser(id);
		System.out.println("microservice-provider2微服务在响应客户端请求……");
		System.out.println("user : " + user);
		return user;
	}

microservice-provider3微服务中UserServiceImpl类中getUser方法修改为如下:

	@Override
	public User getUser(int id) {
		User user = userDao.getUser(id);
		System.out.println("microservice-provider3微服务在响应客户端请求……");
		System.out.println("user : " + user);
		return user;
	}

测试:启动3个eureka的微服务集群,然后启动3个上述提供者微服务,最后启动消费者微服务microservice-consumer,分别从前端发起http://localhost:7001/consumer/get/{id}多笔请求,id用数字代替,发现分别在三个提供者服务的console中输出如下内容:

microservice-provider3微服务在响应客户端请求……
user : User [id=1, name=lzj1, age=20]

microservice-provider3微服务在响应客户端请求……
user : User [id=2, name=lzj2, age=24]

microservice-provider微服务在响应客户端请求……
user : User [id=4, name=lzj4, age=30]

microservice-provider2微服务在响应客户端请求……
user : User [id=3, name=lzj3, age=26]
……

3个提供者微服务随机的响应客户端请求。

3、通过Ribbon的核心组件IRule定义查找消费端调用提供端微服务的策略
如没有指定轮询策略,默认是消费端随机调用提供端微服的策略,下面指定轮询调用策略。只需要在microservice-consumer中的ConfigBean类添加如下声明:

	@Bean
	public IRule myRule(){
		return new RoundRobinRule(); 	//轮询策略
	}

重新启动3个eureka微服务和3个提供者微服务,最后启动消费者微服务,重新测试,可知消费者微服务是轮询调用提供者的3个微服务的。

八、Feign负载均衡

Feign是一个声明式WebService客户端。使用Feign能让编写Web Service客户端更加简单。Feign是对Ribbon的包装,Feign集成了Ribbon。
前面在使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模版化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以,Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在Feign的实现下,我们只需创建一个接口并使用注解的方式来配置它,即可完成对服务提供方的接口绑定,简化了使用Spring cloud Ribbon时,自动封装服务调用客户端的开发量。
Feign既然是对Ribbon的包装,那么Feign也是用在客户端的,即消费端的。下面建立集成Feign的消费端
复制microservice-consumer工程为microservice-consumer-feign
修改microservice-consumer-feign启动类的名字为FeignConsumerApplication;
microservice-consumer-feign的pom文件中增加对Feign的依赖:

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

创建ConsumerService接口,用于包装microservicecloud-provider微服务,以后要调用microservicecloud-provider服务中的方法,只需要调用接口中对应的方法即可:

package com.lzj.springcloud.service;
import java.util.List;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.lzj.springcloud.entity.User;

/*以后调用microservicecloud-provider微服务中的方法,只需要调用下面对应的接口既可以了*/
@FeignClient(value="microservicecloud-provider")
public interface ConsumerService {

	/*调用接口中的get方法,即可以向microservicecloud-provider微服务发送/get/{id}请求*/
	@RequestMapping(value="/get/{id}", method=RequestMethod.GET)
	public User get(@PathVariable("id") int id);
	
	@RequestMapping(value="/add", method=RequestMethod.POST)
	public boolean add(User user);
	
	@RequestMapping(value="/getUser/list", method=RequestMethod.GET)
	public List<User> getAll();
}

修改microservice-consumer-feign中的controller层为

package com.lzj.springcloud.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.lzj.springcloud.entity.User;
import com.lzj.springcloud.service.ConsumerService;

@RestController
public class UserConsumerController {
//	private static String REST_URL_PREFIX = "http://localhost:8002";
	/*直接根据微服务名调用,而不再是根据地址和端口了,运用了eureka的发现功能*/
//	private static String REST_URL_PREFIX = "http://microservicecloud-provider";
//	@Autowired
//	private RestTemplate restTemplate;
	
	@Autowired
	private ConsumerService service;
	
	@RequestMapping(value="/consumer/add")
	public boolean addUser(User user){
		Boolean flag = service.add(user);
		return flag;
	}
	
	@RequestMapping(value="/consumer/get/{id}")
	public User get(@PathVariable("id") int id){
		User user = service.get(id);
		return user;
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@RequestMapping(value="/consumer/list")
	public List<User> getList(){
		List list = service.getAll();
		return list;
	}
}

修改启动类FeignConsumerApplication,在启动类上加启用Feign的注解:

package com.lzj.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages="com.lzj.springcloud.service")
public class FeignConsumerApplication {

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

}

测试,启动microservice-eurake1、microservice-eurake2、microservice-eurake3集群,然后启动microservice-provider、microservice-provider2、microservice-provider3集群,最后启动microservice-consumer-feign微服务。
从浏览器中向消费端发送请求http://localhost:7001/consumer/get/2,响应页面如下
这里写图片描述
Feign通过接口ConsumerService中的get方法调用Rest服务(之前是通过Ribbon+RestTemplate),并在eureka微服务中查找microservicecloud-provider服务,找到后,把请求http://localhost:7001/consumer/get/2发送到microservicecloud-provider微服务。

九、Hystrix断路器

如果一个请求需要调起多个服务时,其中一个服务不通或失败,当大量请求发生时,会导致请求延时和资源浪费。Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
当某个服务单元发生故障之后,通过断路器的故障监控,向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
Hystrix可用于服务熔断、服务降级、服务限流等作用。

1、服务熔断
当某个服务出现异常时,熔断该服务,快速返回指定的错误信息,当服务正常时,恢复熔断。
复制microservice-provider工程为microservice-provider-hystrix;
修改microservice-provider-hystri

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/u010502101/article/details/81989756
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢