写在前面:疫情前夕(19年底),从作者刚毕业实习开始,市面上主流的技术问题和探讨内容全部变成了springboot、springcloud,微服务,镜像容器这些作者在学校听都没听过的东西, 当时面试真痛苦,被打了个措手不及,但是作者是属于那种我命由我不由天的性格,痛定思痛,每天下班后都充电(卷)到凌晨,现在网上也有很多优秀的教程或者说是博文,作者写这篇文章也只是想对曾经的自己一个有交代
微服务
什么是微服务:这里不想用百度百科释义,用马丁.福勒的原话会更好
就目前而言,对于微服务业界并没有一个统一的、标准的定义(While there is no precise definition of this architectural style ) 但通常在其而言,微服务架构是一种架构模式或者说是一种架构风格,它提倡将单一应用程序划分成一组小的服务,每个服务运行独立的自己的进程中,服务之间互相协调、互相配合,为用户提供最终价值。服务之间采用轻量级的通信机制互相沟通(通常是基于 HTTP 的 RESTful API ) 。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等。另外,应尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建,可以有一个非常轻量级的集中式管理来协调这些服务。可以使用不同的语言来编写服务,也可以使用不同的数据存储。
这段话作者奉为经典!!!(ps:他还是《重构》一书作者),这里还是要说一下微服务不等于SpringCloud,微服务只是一个概念,而SpringCloud是框架,所有开发语言只要满足上述架构那么我们就可以称之为是微服务
CAP理论(布鲁尔定理)
CAP理论,指的是在一个分布式系统中,Consistency(一致性)、Availability(可用性)、Partition Tolerance(分区容错性),不能同时成立。
这是任何分布式系统都逃不过的宿命,也就是说要么是AP,要么是CP,要么是CA,但是何为分布式系统呢,就是分散在不同的服务器集群中,如果你只满足CA,也就是说不要分区容错,那么这样的系统并不是分布式系统,举个例子,我们平时用的关系型数据库就是CA
说人话:SpringCloud就是一个微服务工具集,里面的各种组件都是为了“解耦”。一款好软件灵魂一定是“高内聚,低耦合”的,这是作者大学编程第一课老师告诉我的,每每产生的新框架都离不开这个因素。
springcloud的核心组件(这里只列举常用的,还有很多):服务注册中心 、服务网关、远程调用、配置中心、断路器(服务降级和熔断保护)等,下面作者会用一套简单的案例来实现从服务注册到通过网关来进行服务间通信的全过程
开发三核心:约定>配置>编码
服务注册中心(eureka-service)
项目结构
依赖
<?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.6.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cawis</groupId>
<artifactId>eureka-service</artifactId>
<version>1</version>
<name>eureka-service</name>
<description>eureka注册中心</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2021.0.1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--bootstrap.yml支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--eureka服务端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置
bootstrap.yml
server:
port: 4396
spring:
application:
name: eureka-service #eureka的服务名称
#配置eureka服务端登路的用户名和密码
security:
user:
name: admin
password: 123456
eureka:
instance:
hostname: ${spring.application.name}
instance-id: ${spring.application.name}
client:
register-with-eureka: false #禁止自己当做服务注册
fetch-registry: false #屏蔽注册信息
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #注册eureka客户端
server:
#eureka server刷新readCacheMap的时间
response-cache-auto-expiration-in-seconds: 3000
#启用主动失效,并且每次主动失效检测间隔为3s
eviction-interval-timer-in-ms: 3000
logging:
level:
org:
springframework: INFO
file:
name: /logs/${spring.application.name}.log
代码
配置类,这里作者开启了登录页面
package com.cawis.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
public class EurekaSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable();
super.configure(httpSecurity);
}
}
主启动类
package com.cawis;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
//开启用户认证
@EnableWebSecurity
//表示注册中心
@EnableEurekaServer
@SpringBootApplication
public class EurekaServiceApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServiceApplication.class, args);
}
}
效果
启动主启动类并访问http://localhost:4396/并输入账号admin密码123456
eureka启动成功
服务配置中心(config-service)
何为配置中心,每个服务都是有配置文件的,这么多文件就需要一个集中的仓库管理而不是在每个服务里面自己配置,这就是配置中心的作用
项目结构
依赖
<?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.6.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cawis</groupId>
<artifactId>config-service</artifactId>
<version>1</version>
<name>config-service</name>
<description>配置中心</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2021.0.1</spring-cloud.version>
</properties>
<dependencies>
<!--bootstrap.yml支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--配置中心服务端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!--eureka客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置
在这之前要先去gitee新建一个仓库,仓库里面用来存放配置文件
bootstrap.yml
server:
port: 7777
spring:
application:
name: config-service
#从git加载远端配置
cloud:
config:
server:
git:
#仓库的git地址
uri: https://gitee.com/aJieYa/micro-service-yaml.git
#仓库包名
search-paths: /abc
username: 你的gitee账号
password: 你的gitee密码
eureka:
instance:
#使用IP注册
prefer-ip-address: true
#ip-address: 192.168.1.1 #强制指定IP地址,默认会获取本机的IP地址
instance-id: ${spring.cloud.client.ip-address}:${server.port}
hostname: ${spring.cloud.client.ip-address}
lease-renewal-interval-in-seconds: 5
lease-expiration-duration-in-seconds: 10
client:
eureka-server-port: 4396
service-url:
defaultZone: http://admin:123456@${eureka.instance.hostname}:${eureka.client.eureka-server-port}/eureka/
register-with-eureka: true
fetch-registry: true
logging:
level:
org:
springframework: INFO
file:
name: /logs/${spring.application.name}.log
代码
主启动类
package com.cawis;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
//表示配置中心
@EnableConfigServer
@SpringBootApplication
public class ConfigServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServiceApplication.class, args);
}
}
效果
启动主启动类并刷新eureka可以看到config-service已经注册
服务网关(gateway-service)
简单来说网关就是一个接口请求分发器,不同ip端口的服务都要通过这个分发器来分发请求
项目结构
依赖
<?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.6.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cawis</groupId>
<artifactId>gateway-service</artifactId>
<version>1</version>
<name>gateway-service</name>
<description>服务网关</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2021.0.1</spring-cloud.version>
</properties>
<dependencies>
<!--gateway依赖于webflux而不是webmvc所以要单独生成pom依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--bootstrap.yml支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--openfign和gateway的新负载均衡器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<!--配置中心客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--eureka客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置
bootstrap.yml
spring:
cloud:
config:
uri: http://127.0.0.1:7777 #config-server的地址
name: gateway-service #需要从git上读取的配置的名字,不用添加文件后缀
# profile: dev #激活的配置
label: master #git分支
fail-fast: true #是否启动快速失败功能,功能开启则优先判断config server是否正常
git远端gateway-service.yml
server:
port: 9527
spring:
application:
name: gateway-service
cloud:
gateway:
routes: # 路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]
- id: consumer-service # 当前路由的标识, 要求唯一,可以随便写
uri: lb://consumer-service # lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
predicates: # 断言(就是路由转发要满足的条件)
- Path=/consumerservice/** # 当请求路径满足Path指定的规则时,才进行路由转发
filters: # 过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
- StripPrefix=1 # 转发之前去掉1层路径
- id: producer-service
uri: lb://producer-service
predicates:
- Path=/producerservice/**
filters:
- StripPrefix=1
eureka:
instance:
#使用IP注册
prefer-ip-address: true
#ip-address: 192.168.1.1 #强制指定IP地址,默认会获取本机的IP地址
instance-id: ${spring.cloud.client.ip-address}:${server.port}
hostname: ${spring.cloud.client.ip-address}
lease-renewal-interval-in-seconds: 5
lease-expiration-duration-in-seconds: 10
client:
eureka-server-port: 4396
service-url:
defaultZone: http://admin:123456@${eureka.instance.hostname}:${eureka.client.eureka-server-port}/eureka/
register-with-eureka: true
fetch-registry: true
#日志配置
logging:
level:
org:
springframework: INFO
file:
name: /logs/${spring.application.name}.log
代码
主启动类
package com.cawis;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GatewayServiceApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServiceApplication.class, args);
}
}
效果
启动主启动类并刷新eureka可以看到我们的gateway-service已经注册
生产者服务(producer-service)
服务间通信的接口提供方
项目结构
依赖
<?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.6.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cawis</groupId>
<artifactId>producer-service</artifactId>
<version>1</version>
<name>producer-service</name>
<description>生产者</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2021.0.1</spring-cloud.version>
</properties>
<dependencies>
<!--bootstrap.yml支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--配置中心客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--eureka客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置
bootstrap.yml
spring:
cloud:
config:
uri: http://127.0.0.1:7777 #config-server的地址
name: producer-service #需要从git上读取的配置的名字,不用添加文件后缀
profile: dev #激活的配置
label: master #git分支
fail-fast: true #是否启动快速失败功能,功能开启则优先判断config server是否正常
git远端producer-service.yml
eureka:
instance:
#使用IP注册
prefer-ip-address: true
#ip-address: 192.168.1.1 #强制指定IP地址,默认会获取本机的IP地址
instance-id: ${spring.cloud.client.ip-address}:${server.port}
hostname: ${spring.cloud.client.ip-address}
lease-renewal-interval-in-seconds: 5
lease-expiration-duration-in-seconds: 10
client:
eureka-server-port: 4396
service-url:
defaultZone: http://admin:123456@${eureka.instance.hostname}:${eureka.client.eureka-server-port}/eureka/
register-with-eureka: true
fetch-registry: true
logging:
level:
org:
springframework: INFO
file:
name: /logs/${spring.application.name}.log
---
server:
port: 4444
spring:
application:
name: producer-service
profiles: test
---
server:
port: 5555
spring:
application:
name: producer-service
profiles: dev
---
server:
port: 6666
spring:
application:
name: producer-service
profiles: prod
代码
controller对外暴露一个接口
package com.cawis.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProducerController {
@Value("${spring.application.name}")
private String applicationName;
@Value("${spring.profiles}")
private String profiles;
@Value("${server.port}")
private int port;
@GetMapping("/getConfig")
public String getConfig() {
System.out.println("接口被调用");
return "当前服务:" + applicationName + "运行环境:" + profiles+ "端口:" + port;
}
}
主启动类
package com.cawis;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ProducerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ProducerServiceApplication.class, args);
}
}
效果
启动主启动类并刷新eureka可以看到我们的producer-service已经注册
访问http://localhost:9527/producerservice/getConfig可以看到接口被网关统一转发
或者访问http://localhost:5555/getConfig请求生产者自己的接口
现在看起来好像网关能做的我们服务也能做,可是有没有想过这样一个问题,既然是微服务那么肯定不止一个服务如果有成千上万个服务该怎么办(一般不会这么夸张),难道给每个服务的端口配置一个nginx转发么,这个时候就该网关发力了,也就是只需要在nginx里面配置代理后由我们网关转发请求即可
消费者服务(consumer-service)
服务间通信的接口调用方
项目结构
依赖
<?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.6.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cawis</groupId>
<artifactId>consumer-service</artifactId>
<version>1</version>
<name>consumer-service</name>
<description>消费者</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2021.0.1</spring-cloud.version>
</properties>
<dependencies>
<!--feign客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--openfign和gateway的新负载均衡器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<!--bootstrap.yml支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--配置中心客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--eureka客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置
bootstrap.yml
spring:
cloud:
config:
uri: http://127.0.0.1:7777 #config-server的地址
name: consumer-service #需要从git上读取的配置的名字,不用添加文件后缀
profile: dev #激活的配置
label: master #git分支
fail-fast: true #是否启动快速失败功能,功能开启则优先判断config server是否正常
git远端 consumer-service.yml
eureka:
instance:
#使用IP注册
prefer-ip-address: true
#ip-address: 192.168.1.1 #强制指定IP地址,默认会获取本机的IP地址
instance-id: ${spring.cloud.client.ip-address}:${server.port}
hostname: ${spring.cloud.client.ip-address}
lease-renewal-interval-in-seconds: 5
lease-expiration-duration-in-seconds: 10
client:
eureka-server-port: 4396
service-url:
defaultZone: http://admin:123456@${eureka.instance.hostname}:${eureka.client.eureka-server-port}/eureka/
register-with-eureka: true
fetch-registry: true
logging:
level:
org:
springframework: INFO
file:
name: /logs/${spring.application.name}.log
---
server:
port: 1111
spring:
application:
name: consumer-service
profiles: test
---
server:
port: 2222
spring:
application:
name: consumer-service
profiles: dev
---
server:
port: 3333
spring:
application:
name: consumer-service
profiles: prod
代码
远程调用feign,就是被封装的一个接口请求工具
package com.cawis.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
//调用服务名
@FeignClient(name = "producer-service")
public interface ConsumerFeign{
//被调用接口
@GetMapping("/getConfig")
String getConfig();
}
controller这里直接通过feign请求生产者的getConfig接口
package com.cawis.controller;
import com.cawis.feign.ConsumerFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConsumerController {
@Autowired
private ConsumerFeign consumerFeign;
@GetMapping("/getConfig")
public String getConfig() {
String config = consumerFeign.getConfig();
return consumerFeign + config;
}
}
主启动类
package com.cawis;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients
@SpringBootApplication
public class ConsumerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerServiceApplication.class, args);
}
}
效果
启动主启动类并刷新eureka可以看到我们的consumer-service已经注册
访问http://localhost:9527/consumerservice/getConfig可以看到feign远程调用成功
修改生产者配置为test并再启动一个生产者服务
不知道如何启动多个的朋友
Allow parallel run勾选
修改之后再启动ProducerServiceApplication主启动类并刷新eureka可以看到有两个生产者的集群已经注册
此时再重新访问http://localhost:9527/consumerservice/getConfig并多次刷新可以看到接口请求被负载均衡(默认:轮询)
写在最后:至此springcloud-eureka版本微服务已经整合完成并实现了服务间通信,这里作者想说的是,千万不要为了微服务而微服务,这样是不好的,作者之前的项目就踩过这样的坑,一定要考虑到项目的体量以及业务适配度,很理解现在的环境以及大家想充电(卷)的心情,但程序,代码,项目,客户是无辜的,希望大家对得起自己的职业操守以及学编程的初衷,诸君共勉~~