基于Spring Cloud的微服务架构
#摘要
-
Rest
-
微服务基本概念
-
Spring Cloud的微服务解决方案
-
容器与微服务
-
微服务在EMS中的实际应用
#Restful API
-
REST:Representational State Transfer(表现层状态转移)
一种软件架构或设计风格,并没有明确的实现标准,它拥有一组架构约束条件和原则,任何满足这些约束条件或原则的应用程序或设计就是Restful。
-
Restful API
-
资源:每个URL代表一种资源,是一个名词,不包含任何动作。
-
动作:所有对资源的操作映射到标准的HTTP动作中(GET/POST/PUT/DELETE...)。
-
响应:API的响应结果通过http处理状态码返回(2xx/3xx/4xx/5xx)。
-
#什么是微服务
#微服务
-
单体应用:即应用所有功能全部打包成一个独立的单元。
-
优点:架构简单、易于测试及部署。
-
缺点:代码庞大、缺乏灵活、难以持续交付、技术债务。
-
-
微服务:是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。
-
单一职责(业务)
-
规范接口
-
独立部署
-
轻量级(REST)
-
-
优点:
-
服务界限清晰、业务独立;
-
持续交付、快速部署;
-
弹性伸缩(扩展性)。
-
-
缺点
-
服务架构复杂,部署运维难度较大;
-
测试难度大。
-
#基于Spring Cloud搭建简单微服务架构
#EMS的微服务应用
#干货-基于Spring Cloud搭建基本微服务架构(手把手)
#服务结构
-
简单微服务架构
-
spring-cloud-config-server:配置中心
-
spring-cloud-eureka-server:服务注册/发现中心
-
spring-cloud-zuul:服务网关
-
biz-servcie-a:后端业务服务A
-
biz-service-b:后端业务服务B
-
#搭建配置管理中心:spring-cloud-config-server
使用Spring Cloud Config搭建微服务配置管理中心
-
maven依赖:pom.xml
<?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">
<parent>
<artifactId>spring-cloud-demo</artifactId>
<groupId>org.bin</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-config-server</artifactId>
<dependencies>
<!-- spring cloud config -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<version>1.3.1.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
<version>1.5.3.RELEASE</version>
</dependency>
</dependencies>
</project>
-
启动类:Application.class
package org.cent.demo.config; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; /** * @author dengbin * @date 2019-08-08 */ @SpringBootApplication @EnableConfigServer public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
搭建服务注册中心:spring-cloud-eureka-server
使用Spring Cloud Eureka Server搭建服务注册(发现)中心
Maven 依赖:pom.xml
<?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">
<parent>
<artifactId>spring-cloud-demo</artifactId>
<groupId>org.bin</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-eureka-server</artifactId>
<dependencies>
<!-- spring boot web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.5.3.RELEASE</version>
</dependency>
<!-- eureka server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<version>1.3.1.RELEASE</version>
</dependency>
<!-- spring cloud config -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>1.3.1.RELEASE</version>
</dependency>
</dependencies>
</project>
配置文件:bootstrap.yml
spring:
cloud:
config:
uri: http://localhost:8000/
name: spring-cloud-eureka-server
- 配置文件: spring-cloud-eureka-server.yml
server:
port: 8001
eureka:
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://localhost:${server.port}/eureka/
-
启动类
ackage org.cent.demo.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* @author dengbin
* @date 2019-08-08
*/
@SpringBootApplication
@EnableEurekaServer
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
搭建网关服务:spring-cloud-zuul
基于Netflix Zuul搭建API网关服务
- maven 依赖的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"> <parent> <artifactId>spring-cloud-demo</artifactId> <groupId>org.bin</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-cloud-zuul</artifactId> <dependencies> <!-- zuul --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> <version>1.3.1.RELEASE</version> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> <version>1.5.3.RELEASE</version> </dependency> <!-- eureka --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> <version>1.3.1.RELEASE</version> </dependency> <!-- ribbon --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> <version>1.3.1.RELEASE</version> </dependency> <!-- config --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> <version>1.3.1.RELEASE</version> </dependency> </dependencies> </project>
- 配置文件:bootstarp.yml
spring:
cloud:
config:
uri: http://localhost:8000/
name: spring-cloud-zuul
- 配置文件:spring-cloud-zuul.yml
server:
port: 80
spring:
application:
name: spring-cloud-zuul
# 服务注册中心配置
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8001/eureka/
registry-fetch-interval-seconds: 5
instance:
lease-renewal-interval-in-seconds: 10 # 心跳时间,即服务续约间隔时间(缺省为30s)
lease-expiration-duration-in-seconds: 60 # 发呆时间,即服务续约到期时间(缺省为90s)
prefer-ip-address: true
instanceId: ${spring.application.name}:${spring.application.instance_id:${server.port}}
# 网关配置
zuul:
host:
max-per-route-connections: 1000
max-total-connections: 1000
socket-timeout-millis: 60000
connect-timeout-millis: 1000
sensitiveHeaders: Cookie,Set-Cookie
# 断路器配置
hystrix:
command:
default:
execution:
timeout:
enabled: true
isolation:
thread:
timeoutInMilliseconds: 60000
# 负载均衡配置
ribbon:
ReadTimeout: 60000
ConnectTimeout: 1000
MaxAutoRetries: 3
MaxAutoRetriesNextServer: 1
biz-service-a:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
biz-service-b:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
- 启动类:Application.class
-
package org.cent.demo.zuul; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; /** * @author dengbin * @date 2019-08-08 */ @SpringBootApplication @EnableZuulProxy public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
搭建业务服务:biz-service-a&biz-service-b
搭建service-a和service-b两个业务服务,依赖配置如下:
-
Maven依赖:pom.xml
<?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">
<parent>
<artifactId>spring-cloud-demo</artifactId>
<groupId>org.bin</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>biz-service-a</artifactId>
<dependencies>
<!-- spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.5.3.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
<version>1.5.3.RELEASE</version>
</dependency>
<!-- spring cloud config -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>1.3.1.RELEASE</version>
</dependency>
<!-- eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.3.1.RELEASE</version>
</dependency>
</dependencies>
</project>
- 服务配置文件:bootstrap.yml
# config server
spring:
cloud:
config:
uri: http://localhost:8000/
name: biz-service-a #biz-service-b
- 配置文件:biz-service-a/b.yml
spring:
application:
name: biz-service-a/b
server:
port: 8010
# 服务注册中心配置
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8001/eureka/
registry-fetch-interval-seconds: 5
instance:
lease-renewal-interval-in-seconds: 10 # 心跳时间,即服务续约间隔时间(缺省为30s)
lease-expiration-duration-in-seconds: 60 # 发呆时间,即服务续约到期时间(缺省为90s)
prefer-ip-address: true
instanceId: ${spring.application.name}:${spring.application.instance_id:${server.port}}
- 启动类:Application.class
-
package org.cent.demo.service_b; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; /** * @author dengbin * @date 2019-08-08 */ @SpringBootApplication @EnableEurekaClient public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }