搭建SpringCloud 系列demo

总工程microservice-parent

<?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的公共模块

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

在该模块中建立一个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 + "]";
	}
	
}

microservice-provider微服务

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

在pom文件中引入了microservice-com的依赖

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

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                                             # 数据库连接池的最小维持连接数

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>

创建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();
}

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

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();
}

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;
	}

}

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;
	}
}

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);
	}

}

测试microservice-provider微服

http://localhost:8002/getUser/list

microservice-consumer微服务

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

application.yml

server: 
  port: 8003

置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();
	}
}

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;
	}
}

启动类

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);
	}

}

测试

http://localhost:8003/consumer/add?name=lzj5&age=35

microservice-eurake1微服务
eureka微服务用于注册和发现服务。

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

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

启动类
@EnableEurekaServer注解,该注解用于激活eureka的服务端。

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);
	}

}

正确创建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微服务中的application.yml文件中加入如下配置
表示把microservice-provider微服务注册进http://localhost:9001/eureka指示的服务中,即microservice-eureka微服务中。

修改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);
	}

}

启动测试即可

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
默认情况下,如果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改为(因为之前该微服是复制过来的,如果是创建过来的就不用修改)microservice-eurake2
把microservice-eurake3服务中pom文件中的artifactId改为microservice-eurake3

修改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$

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/

@LoadBalanced

负载均衡实际是根据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;
	}
}

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$

为方便观察哪一个提供者微服务响应的客户端请求,在提供者微服中分别打印两条日志,
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;
	}

其他priovider服务也如此

测试

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);
	}

}

测试

Hystrix断路器

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

1、服务熔断
当某个服务出现异常时,熔断该服务,快速返回指定的错误信息,当服务正常时,恢复熔断。
复制microservice-provider工程为microservice-provider-hystrix;
修改microservice-provider-hystrix的启动类为HystrixProviderApplication;
pom文件中添加hystrix的依赖

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

application.yml

server: 
  port: 8005

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-provider-hystrix           #自定义服务名称信息
    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;
修改UserController内容为:

package com.lzj.springcloud.controller;
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.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.lzj.springcloud.entity.User;
import com.lzj.springcloud.service.UserService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

@RestController
public class UserController {
    
    

	@Autowired
	private UserService service;
	
	@RequestMapping(value="/get/{id}", method=RequestMethod.GET)
	@HystrixCommand(fallbackMethod="hystrixGetUser") //一旦服务调用失败,就调用hystrixGetUser方法
	public User getUser(@PathVariable("id") int id){
    
    
		User user = service.getUser(id);
		if(user == null){
    
    
			throw new RuntimeException("不存在id=" + id + "对应的用户信息");
		}
		return user;
	}
	
	public User hystrixGetUser(@PathVariable("id") int id){
    
    
		User user = new User(id, "不存在该用户", 0);
		return user;
	}

}

在启动类HystrixProviderApplication上添加注解@EnableCircuitBreaker;
启动microservice-eurake1、microservice-eurake2、microservice-eurake3服务,然后启动microservice-provider-hystrix服务,然后启动microservice-consumer-feign服务。

测试

2、服务降级
在一个分布式系统中,当访问高峰期或资源有限时,需要关掉某个服务,若有请求访问该服务,不能因为系统服务关掉了,就一直中断在该调用服务处,这时就需要请求返回指定的错误信息。例如在分布式系统中有A、B两个服务,因为资源有限,需要关掉B服务,A服务在调用B服务时,没有调通,此时A返回指定的错误信息,注意不是在B服务端返回的,是A客户端返回的错误信息。看示例
复制microservice-consumer-feign服务为microservice-consumer-feign-hystrix;
microservice-consumer-feign-hystrix的pom文件中添加依赖:

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

microservice-consumer-feign-hystrix服务中新建实现FallbackFactory的ConsumerServiceFallbackFactory类,在类上添加@Component,并传入ConsumerService接口,当调用ConsumerService中对应的方法失败后,自动调用ConsumerServiceFallbackFactory 中对应实现的ConsumerService方法,并在对应方法中定制调用服务失败后显示的错误信息。

package com.lzj.springcloud.service;
import java.util.List;
import org.springframework.stereotype.Component;
import com.lzj.springcloud.entity.User;
import feign.hystrix.FallbackFactory;

@Component
public class ConsumerServiceFallbackFactory implements FallbackFactory<ConsumerService> {
    
    

	@Override
	public ConsumerService create(Throwable arg0) {
    
    
		// TODO Auto-generated method stub
		return new ConsumerService() {
    
    
			
			@Override
			public List<User> getAll() {
    
    
				// TODO Auto-generated method stub
				return null;
			}
			
			@Override
			public User get(int id) {
    
    
				User user = new User(id, "该用户不存在", 0);
				return user;
			}
			
			@Override
			public boolean add(User user) {
    
    
				// TODO Auto-generated method stub
				return false;
			}
		};
	}

}

在microservice-consumer-feign-hystrix服务中ConsumerService的接口中@FeignClient中添加fallbackFactory属性。运用spring的AOP切面,当调用ConsumerService中方法失败后,执行fallbackFactory属性指定的ConsumerServiceFallbackFactory类中的对应方法,ConsumerService修改后如下:

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", fallbackFactory=ConsumerServiceFallbackFactory.class)
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-hystrix服务的application.yml文件为:

server: 
  port: 7001

feign: 
  hystrix: 
    enabled: true

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

测试

3、服务监控
hystrix除了应用于上述的服务熔断和降级,还可以应用于服务的实时监控。Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求多少成功,多少失败等。Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。Spring Cloud也提供了Hystrix Dashboard的整合,对监控内容转化成可视化界面。示例如下
创建microservice-consumer-hystrix-dashbord微服务;
添加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>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-hystrix</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-hystrix-dashboard</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>

application.yml配置文件如下:

server: 
  port: 7002

创建启动类HystrixDashbordConsumerApplication:

package com.lzj.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;

@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashbordConsumerApplication {
    
    

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

}

测试

Zuul路由

Zuul路由包含了对请求的路由和过滤两个功能。
路由:路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口;
过滤:过滤器功能则负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础。
Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获得其他微服务的消息,也即以后的访问微服务都是通过Zuul跳转后获得。Zuul服务最终也会注册进Eureka。

1、路由配置
建立一个microservice-zull微服务;
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-zull</artifactId>
  
	<dependencies>
		<!-- zuul路由网关 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-zuul</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>

也要把Zuul微服务注册到Eureaka上面,application.yml文件配置如下:

server: 
  port: 6001

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

在host文件中添加127.0.0.1的映射,127.0.0.1 zull6001.com用zull6001.com表示Zuul微服务的域名;
创建ZullApplication启动类,内容如下:

package com.lzj.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableZuulProxy //启动Zuul
public class ZullApplication {
    
    

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

}

测试

2、修改服务代理名称
上面通过路由访问服务的请求为http://zull6001.com:6001/microservicecloud-provider/get/2,其中microservicecloud-provider为调用的服务名,向调用方暴露了具体的服务名。如果不想暴露服务名,可以为服务指定一个代号别名,例如可以通过发送请求http://zull6001.com:6001/provider/get/2访问microservicecloud-provider服务,那么provider即为microservicecloud-provider的别名,在application.yml中配置如下:

server: 
  port: 6001

spring:
  application:
    name: microservice-zull
eureka:
  client:
    service-url: 
      defaultZone: http://eureka9003.com:9003/eureka/,http://eureka9002.com:9002/eureka/,http://eureka9001.com:9001/eureka/
  instance: 
    instance-id: microservice-zull6001                        #自定义服务名称信息
    prefer-ip-address: true                                   #访问路径可以显示IP地址
    
zuul:
  routes:
    mydept.serviceId: microservicecloud-provider
    mydept.path: /provider/**

info: 
  app.name: microservice-zull
  company.name: www.lzj.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$

忽略带真实服务名的请求

zuul:
  ignored-services: microservicecloud-provider
  routes:
    mydept.serviceId: microservicecloud-provider
    mydept.path: /provider/**

设置访问前缀

zuul:
  prefix: /MyDemo
  ignored-services: microservicecloud-provider
  routes:
    mydept.serviceId: microservicecloud-provider
    mydept.path: /provider/**

Config配置

一个分布式系统有可能包括非常多微服务,每个微服务都有独自的配置文件,当系统变更时,有可能需要修改很多服务的配置文件,导致运维繁琐,容易出问题,所以需要一套集中式的、动态的配置管理设施。spring cloud提供了Config来解决该问题。

1、建立Config服务端,与github通信
在github上建立一个respository,此地名为microservice-config,地址为:https://github.com/shuniversity/microservice-config.git;
把建立的respository 克隆到本地E:\demo\springcloud-config-repository

>git clone https://github.com/shuniversity/microservice-config.git

在clone到本地的仓库E:\demo\springcloud-config-repository\microservice-config中新建一个application.yml文件,内容为:

spring:
  profiles:
    active:
      - dev
---
spring:
  profiles: dev                   #开发环境
  application:
    name: microservice-config-dev
    
---
spring:
  profiles: test                  #测试环境
  application:
    name: microservice-config-test

把新建的application.yml文件推送到github上的microservice-config仓库中:

    git add .
    git commit -m "init file" 
    git push origin master

新建microservice-config-server服务,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-config-server</artifactId>
  
	<dependencies>
		<!-- 依赖microservice-com模块 -->
		<dependency>
    		<groupId>org.springframework.cloud</groupId>
    		<artifactId>spring-cloud-config-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>

application.yml配置为:
server:
port: 4001

spring:
  application:
    name: microservice-config-server
  cloud:
    config:
      server:
        git:
          uri: https://github.com/shuniversity/microservice-config.git

建立启动类ConfigServerApp

package com.lzj.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApp {
    
    

	public static void main(String[] args) {
    
    

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

}

猜你喜欢

转载自blog.csdn.net/qq_36644198/article/details/116424420
今日推荐