文章目录
开发工具及环境
工具:Intellij IDEA
环境:Java 1.8 maven
一、为什么使用微服务?
重点:节约成本,提高性能
举一个简单明了的例子,传统服务电商平台的重点是订单处理,如果不能下单,这个平台一切都没什么意义。当遇到双十一等活动的时候,服务器不足以支撑这么大的请求时候该怎么办?当然先可以搭建集群,当集群也不行的时候只能扩大服务器。但是其他的地方如商品管理、用户管理等不需要这么大的服务器。由于就一个订单的处理提升了整个平台的服务器,浪费了成本。所以此时就需要微服务的出现,把整个电商分解成微服务,如订单服务,用户服务,商品服务等。单独给订单服务配一个好的服务器,就解决了上诉问题。(个人理解)
二、微服务各组件的用途
1.eureka(注册中心)
所有的微服务模块统一到注册中心注册,生成注册表,进行统一管理。eureka既可以是生产者,也可以是消费者。
当然也可以搭建集群,如果其中一个eureka崩了,也不会影响其他微服务的使用,提高系统的性能。(下文会有具体搭建eureka集群的过程)
2.ribbon(负载均衡)
ribbon最牛的地方RoundRobinRule轮询算法,默认的是每个服务按顺序请求一次。
服务之间也需要进行通信,可以采用http或rpc(远程过程调用)。可以采用RestTemplate,RestTemplate内部封装了http,返回object,使用更方便快捷。
3.zuul(网关)
通俗的讲,是一个关口,想让那些东西通过就可以通过,不想让哪些东西通过就不能通过。
当请求从客服端发到服务器,如果经过网关的一系列验证和过滤符合访问要求,那么在之后访问其他微服务或由网关路由转发之后的访问时,不需要再做同样的安全认证。
4.Hystrix(熔断器)
简单来说,相当于电路中的保险丝。
举个例子说明下熔断器的用途。商品下单会调用订单服务,然后订单服务会通知仓库服务发货、订单服务通知积分服务给用户新增积分。如果积分服务挂了,每次订单服务请求积分服务线程会等待几秒钟然后返回一个异常。如果做秒杀的时候,大量的订单服务线程卡在积分服务这里,然后订单服务也挂了,完犊子,雪崩,整个服务炸了。如果第一次请求积分服务的时候发现它挂了,就不在管他,各服务都做它该做的事。这时就会用到Hystrix。最后积分服务进行降级处理,给用户一个提示,积分服务出现异常,待人工核实后添加积分。大不了最后积分服务恢复后人工进行积分处理,不影响整个服务的使用。Hystrix里面有个性能非常好,如果发现积分服务挂了,Hystrix自动打开,一段时间后,Hystrix会半开,放一个请求过积分服务,问问积分服务怎么样了,如果积分服务还挂着,Hystrix就继续打开,一旦积分服务请求成功,Hystrix自动关闭。(Hystrix小伙子是真的不错,让人也太省心了)
三、微服务的搭建(仔细看内容,最后有源码)
1.eureka集群的搭建
(1) 先新建一个空项目 file ------> new -----> project
设置项目名称springcloudmicroserives
(2)添加eureka模块 file ----->new ----->modules
选择spring web 和 eureka server
下面是eureka的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>注册中心</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--添加热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--fork:如果没有该项配置,整个devtools不会起作用-->
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
(3)因为我们要搭建eureka的集群,所以先去改个文件C:\Windows\System32\drivers\etc 用记事本打开hosts 添加上
127.0.0.1 peer1
127.0.0.1 peer2
127.0.0.1 peer3
然后配置application.yml文件
application.yml
---
spring:
application:
name: spring-cloud-eureka
profiles: peer1
server:
port: 8000
eureka:
instance:
hostname: peer1
client:
serviceUrl:
defaultZone: http://peer2:8001/eureka/,http://peer3:8002/eureka/
fetch-registry: false
register-with-eureka: false
server:
#注意:更改Eureka更新频率将打破服务器的自我保护功能,生产环境下不建议自定义这些配置。
eviction-interval-timer-in-ms: 4000 # 清理间隔(单位毫秒,默认是60*1000)
#关闭注册中心的保护机制, 默认false, 不推荐关闭
#eureka.server.enable-self-preservation: false
---
spring:
application:
name: spring-cloud-eureka
profiles: peer2
server:
port: 8001
eureka:
instance:
hostname: peer2
client:
serviceUrl:
defaultZone: http://peer1:8000/eureka/,http://peer3:8002/eureka/
fetch-registry: false
register-with-eureka: false
---
spring:
application:
name: spring-cloud-eureka
profiles: peer3
server:
port: 8002
eureka:
instance:
hostname: peer3
#Eureka client 默认 30秒会向 Server 端发送一次心跳;
#Server端 默认是90秒对没有接收到 client 端的续租请求会认为client挂机
#lease-renewal-interval-in-seconds: 10
client:
serviceUrl:
defaultZone: http://peer2:8001/eureka/,http://peer1:8000/eureka/
fetch-registry: false
register-with-eureka: false
(4)设置不同的端口启动 添加上peer1 ,复制,粘贴俩次,然后把peer1分别修改为peer2和peer3
(4)在启动器里添加上@EnableEurekaServer注解,eureka的集群就搭建成功了
我们分别启动这三个eureka服务。
各eureka服务相互注册,搭建成功
2.订单服务搭建
(1)新建模块
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>order</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>订单模块</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.17</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--添加热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
<!-- hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.6.RELEASE</version>
</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>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--fork:如果没有该项配置,整个devtools不会起作用-->
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml文件 连接自己的数据库
defaultZone: http://
e
u
r
e
k
a
.
i
n
s
t
a
n
c
e
.
h
o
s
t
n
a
m
e
:
8000
/
e
u
r
e
k
a
/
,
h
t
t
p
:
/
/
{eureka.instance.hostname}:8000/eureka/,http://
eureka.instance.hostname:8000/eureka/,http://{eureka.instance.hostname}:8001/eureka/,http://${eureka.instance.hostname}:8002/eureka/这里向3个eureka注册服务,因为你有可能不知道哪个服务开启,所以都注册
server:
port: 8705 # 服务提供方
# 指定当前eureka客户端的注册地址,
eureka:
client:
service-url:
defaultZone: http://${eureka.instance.hostname}:8000/eureka/,http://${eureka.instance.hostname}:8001/eureka/,http://${eureka.instance.hostname}:8002/eureka/
instance:
hostname: localhost
#当前服务名称
spring:
application:
name: order
servlet:
multipart:
enabled: true
max-file-size: 500MB
max-request-size: 500MB
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=UTF8&useSSL=false&serverTimezone=UTC
username: root
password: 123456
jpa:
hibernate.ddl-auto: update
show-sql: true
ribbon:
ReadTimeout=60000
ConnectTimeout=60000
MaxAutoRetries=0
MaxAutoRetriesNextServer=1
(2)添加注解和负载均衡
(3)shopController代码
package com.example.order.controller;
import com.example.order.entity.Shop;
import com.example.order.service.ShopService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
/**
* Created by IntelliJ IDEA.
* User: xiao
* Date: 2020/9/4
*/
@RequestMapping("/shop")
@RestController
public class ShopController {
@Autowired
private ShopService shopService;
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/find")
@HystrixCommand(fallbackMethod = "processHystrix_Get")
public String findShopById(@RequestParam Integer id) {
Shop shop = shopService.findShopById(id);
String forObject = "";
if (shop != null) {
forObject = restTemplate.getForObject("http://depository/shopDep/save?id=" + id, String.class);
return "下单成功"+"++++++++++++" + forObject;
}
if(shop==null){
throw new RuntimeException("该ID:" + id +"没有没有对应的信息!");
}
return "系统异常";
}
/**
* 发生异常的时候,会调用这个方法来处理
* @param id
* @return
*/
public String processHystrix_Get(@PathVariable("id") Integer id){
return "该ID:" + id + "没有没有对应的信息--@HystrixCommand";
}
}
(4)重点说下如下内容
(5)看下结果,因为还没有仓库服务,所以是如下结果
3.仓库服务搭建
(1)和订单服务搭建流程一样,我直接给出pom和yml文件
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>depository</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>仓库模块</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.17</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<!--添加热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--fork:如果没有该项配置,整个devtools不会起作用-->
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
server:
port: 8706 # 服务提供方
# 指定当前eureka客户端的注册地址,
eureka:
client:
service-url:
defaultZone: http://${eureka.instance.hostname}:8000/eureka/,http://${eureka.instance.hostname}:8001/eureka/,http://${eureka.instance.hostname}:8002/eureka/
instance:
hostname: localhost
#当前服务名称
spring:
application:
name: depository
servlet:
multipart:
enabled: true
max-file-size: 500MB
max-request-size: 500MB
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/shopDep?useUnicode=true&characterEncoding=UTF8&useSSL=false&serverTimezone=UTC
username: root
password: 123456
jpa:
hibernate.ddl-auto: update
show-sql: true
ribbon:
ReadTimeout=60000
ConnectTimeout=60000
MaxAutoRetries=0
MaxAutoRetriesNextServer=1
(2)配置启动
(3)shopDepController
package com.example.depository.controller;
import com.example.depository.service.ShopDeoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by IntelliJ IDEA.
* User: xiao
* Date: 2020/9/4
*/
@RequestMapping("/shopDep")
@RestController
public class ShopDepController {
@Autowired
private ShopDeoService shopDeoService;
@RequestMapping("/save")
public String save(Integer id){
System.out.println(id);
shopDeoService.save(id);
return "商品已出库";
}
}
(4)启动仓库服务,看下结果 商品出库,说明进行了服务间通信
4.网关服务搭建(zuul)
(1)还是新建模块
pom文件和yml文件
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>zuul</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>网关模块</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<!--添加热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--fork:如果没有该项配置,整个devtools不会起作用-->
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
server:
port: 9100
spring:
application:
name: zuul
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka/ #当前zuul网关想要注册到哪个注册中心这里注册到之前搭的9000上。
#路由规则定义。这里定义两种路由规则route1和route2
#,代表访问网关/test01/**或/test02/**时。
#路由到服务名为 eurekaservice1或 eureka
#service2中的服务集群去。
zuul:
routes:
route1:
path: /test01/**
serviceId: eurekaservice1
route2:
path: /test02/**
serviceId: eurekaservice2
(2)配置启动器
(3)启动网关服务,出现下图,配置成功,该网关已在eureka注册
5.搭建4个服务(测试网关用途)
(1)还是新建模块,4个都一样(除了yml文件)
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>service01</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>网关测试模块一</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--添加热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--fork:如果没有该项配置,整个devtools不会起作用-->
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
(2)这里重点说下yml文件。
请求会根据网关服务里的yml里serviceId名字去找相应的服务。
请求会根据网关服务里的yml里serviceId名字去找相应的服务。
请求会根据网关服务里的yml里serviceId名字去找相应的服务。
说了3次,知道他是重点了吧!!!
(3)配置启动器(4个都一样)
package com.example.service01;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableDiscoveryClient
public class Service01Application {
@Bean
@LoadBalanced //客户端的负载均衡器
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(Service01Application.class, args);
}
}
(4)再给下4个服务的controller
package com.example.service01.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by IntelliJ IDEA.
* User: xiao
* Date: 2020/9/9
*/
@RestController
public class Test {
@RequestMapping("/service1")
public String test01(){
return "服务1";
}
}
package com.example.service02.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by IntelliJ IDEA.
* User: xiao
* Date: 2020/9/9
*/
@RestController
public class Test {
@RequestMapping("/service1")
public String test01(){
return "服务2";
}
}
package com.example.service03.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by IntelliJ IDEA.
* User: xiao
* Date: 2020/9/9
*/
@RestController
public class Test {
@RequestMapping("/service2")
public String test01(){
return "服务3";
}
}
package com.example.service04.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by IntelliJ IDEA.
* User: xiao
* Date: 2020/9/9
*/
@RestController
public class Test {
@RequestMapping("/service2")
public String test01(){
return "服务4";
}
}
(5)启动4个服务,我们先预测下结果
因为采用了客户端负载均衡,有一个轮询算法,又是通过网关去访问。所以真相只有一个:第一次访问http://localhost:9100/test01/service1 出现服务1, 刷新之后,出现服务2,再刷新,又是服务1。
当然访问http://localhost:9100/test02/service2也是一个道理。接下来就是见证奇迹的时刻。
总结
首先把源码给大家:https://github.com/xiaodongzai-x/Microservices
然后我想说句话:纸上得来终觉浅,绝知此事要躬行。
最好大家可以亲自动手去练习一下,才能体会微服务的魅力。
最后如果大家觉得文章还不错,请记得点个赞啊!!创作不易,感谢支持。