一、 先了解下SpringCloud微服务的设计理念和初衷。
- 业务分层更细致,对应的服务写对应的业务。服务之间解耦,一台工作某业务的服务挂了不影响其他服务。
- 分布式部署,多服务分摊压力。可伸缩扩展。
- 服务治理,提供了一套完整的服务治理解决方案,有活跃的社区,丰富的组件。
- 缺点:微服务过多,治理成本高,不利于维护系统。
- 缺点:分布式系统开发的成本高(容错,分布式事务等)对团队挑战大.
二、SpringCloud的一些组件
- 服务注册中心:nacos,eureka(功能单一)。
- 配置中心:nacos,Spring Cloud Config.
- 网关:gateway
- 断路器: Hystrix,sentinel
- 服务调用: Ribbon,Feign
- 链路追踪:SkyWalking
三、搭建步骤
首先用idea搭建一个Maven主工程,删除rsc,只保留pom.xml,主pom只控制cloud版本 和springBoot版本。
<?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>
<groupId>com.cloud</groupId>
<artifactId>cloudDemo</artifactId>
<packaging>pom</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>cloudDemo</name>
<description>cloudDemo</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.7.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring.cloud.alibaba.version>2.2.3.RELEASE</spring.cloud.alibaba.version>
<spring.cloud.version>Hoxton.SR6</spring.cloud.version>
<cloudDemo.version>0.0.1-SNAPSHOT</cloudDemo.version>
<spring.boot.version>2.3.7.RELEASE</spring.boot.version>
<nacos.version>2.2.3.RELEASE</nacos.version>
</properties>
<!--全局引入下载依赖地址,并不会引入依赖-->
<dependencyManagement>
<dependencies>
<!--阿里巴巴下载仓库-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--springcloud下载仓库-->
<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>
</project>
二。通过IDEA在 cloudDemo 下建立一个子模块cloud-commons,作为公用基础模块,所有服务需要用到的实体类,工具类,枚举,开源工具需要的引入的依赖都放入cloud-commons 的依赖。统一在cloud-commons管理公用依赖,如有个别服务需要特殊引用依赖,则放在自己的服务pom中。里面的resources文件内容删掉,不需要。
可以看到里面有ali的easyexcel, elasticsearch,nacos,openfeign,nacos-config
lombok。 然后每个自服务都引入 cloud-commons 包就能用到以上的依赖
<?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>cloudDemo</artifactId>
<groupId>com.cloud</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-commons</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!--nacos client-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>${nacos.version}</version>
</dependency>
<!-- ES搜索引擎 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.6.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.6.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.6.1</version>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>0.2.3</version>
</dependency>
<!--openfeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
<!--(nacos统一配置中心管理依赖)-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
<!--sentinel 哨兵 依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
<version>11.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${apache.poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${apache.poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>${apache.poi.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>${easy.excel.version}</version>
</dependency>
</dependencies>
</project>
cloud-commons中的目录结构如下:
三、通过IDEA在 cloudDemo 下建立一个子模块 product,pom如下:
此时commons 中的依赖 product 都可用
<?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">
<parent>
<artifactId>cloudDemo</artifactId>
<groupId>com.cloud</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<groupId>com.example</groupId>
<artifactId>product</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>product</name>
<description>product</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<!-- 公共模块,实体类,工具类,公用模块 -->
<dependency>
<groupId>com.cloud</groupId>
<artifactId>cloud-commons</artifactId>
<version>${cloudDemo.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<configuration>
<mainClass>com.example.product.ProductApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
来看下product的yml:
server:
port: 8082
spring:
profiles:
active: dev
application:
name: product
cloud:
nacos:
server-addr: localhost:8848
discovery:
server-addr: ${spring.cloud.nacos.server-addr}
namespace: ee751565-14dd-4654-8ad3-1d8c046189fd
config:
server-addr: ${spring.cloud.nacos.server-addr}
namespace: ee751565-14dd-4654-8ad3-1d8c046189fd
group: DEV_GROUP
file-extension: yaml
extension-configs:
- data-id: product-dev.yml
group: DEV_GROUP
refresh: true
- data-id: product-dev.yml
group: DEFAULT_GROUP
refresh: true
enabled: true
refresh-enabled: true
# sentinel:
# enabled: true
# eager: true
# transport:
# dashboard: localhost:8718
# port: 8718
# aop:
# #采用CGLIB作为作为动态代理,默认true 为了解决使用 JDK 动态代理可能导致的类型转化异常而默认使用 CGLIB (boot1.x版本默认是false)
# proxy-target-class: true
# #是否开启aop自动配置,默认为true
# #意味着自动加上 @EnableAspectAutoProxy 注解
# #该注解用于开启AOP相关注解得支持
# auto: true
# 正确配置:
#nacos:
# config:
# server-addr: 127.0.0.1:8848
# type: yaml
# bootstrap:
# enable: true
# discovery:
# server-addr: 127.0.0.1:8848
启动类上的注解:
package com.example.product;
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
//@NacosPropertySource(dataId = "product-dev.yml", groupId = "DEV_GROUP",autoRefreshed = true)
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
}
四、通过IDEA在 cloudDemo 下建立一个子模块 user,pom如下:
此时commons 中的依赖 user都可用
<?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>
<groupId>com.cloud</groupId>
<artifactId>cloudDemo</artifactId>
<packaging>pom</packaging>
<version>0.0.1-SNAPSHOT</version>
<modules>
<module>cloud-commons</module>
<module>user</module>
<module>product</module>
<module>cloud-gateway</module>
</modules>
<name>cloudDemo</name>
<description>cloudDemo</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.7.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring.cloud.alibaba.version>2.2.3.RELEASE</spring.cloud.alibaba.version>
<spring.cloud.version>Hoxton.SR6</spring.cloud.version>
<cloudDemo.version>0.0.1-SNAPSHOT</cloudDemo.version>
<spring.boot.version>2.3.7.RELEASE</spring.boot.version>
<easy.excel.version>3.0.5</easy.excel.version>
<apache.poi.version>4.1.2</apache.poi.version>
<nacos.version>2.2.3.RELEASE</nacos.version>
</properties>
<!--全局引入下载依赖地址,并不会引入依赖-->
<dependencyManagement>
<dependencies>
<!--阿里巴巴下载仓库-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--springcloud下载仓库-->
<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>
</project>
来看下 user 的yml:
server:
port: 8081
servlet:
context-path=/ems: /ems
spring:
profiles:
active: dev
application:
name: user
elasticsearch:
rest:
username: elastic
password: 123456
uris: 127.0.0.1:9200
cloud:
nacos:
server-addr: localhost:8848
discovery:
server-addr: ${spring.cloud.nacos.server-addr}
namespace: ee751565-14dd-4654-8ad3-1d8c046189fd
config:
server-addr: ${spring.cloud.nacos.server-addr}
namespace: ee751565-14dd-4654-8ad3-1d8c046189fd
group: DEV_GROUP
file-extension: yaml
extension-configs:
- data-id: user-dev.yml
group: DEV_GROUP
refresh: true
- data-id: user-dev.yml
group: DEFAULT_GROUP
refresh: true
enabled: true
refresh-enabled: true
elasticsearch:
connectTimeout: 1000 # http连接超时时间
socketTimeout: 30000 # socket连接超时时间
connectionRequestTimeout: 500 # 获取连接的超时时间
maxConnTotal: 100 # 最大连接数
maxConnPerRoute: 100 # 最大路由连接数
executeTimeout: 8 # 任务最长可执行时间 (单位:小时)
# sentinel:
# enabled: true
# eager: true
# transport:
# dashboard: localhost:8718
# port: 8718
# aop:
# #采用CGLIB作为作为动态代理,默认true 为了解决使用 JDK 动态代理可能导致的类型转化异常而默认使用 CGLIB (boot1.x版本默认是false)
# proxy-target-class: true
# #是否开启aop自动配置,默认为true
# #意味着自动加上 @EnableAspectAutoProxy 注解
# #该注解用于开启AOP相关注解得支持
# auto: true
# 正确配置:
#nacos:
# config:
# server-addr: 127.0.0.1:8848
# type: yaml
# bootstrap:
# enable: true
# discovery:
# server-addr: 127.0.0.1:8848
feign:
okhttp:
enabled: true
再看看启动类,启动类上加了服务调用的注解,@EnableFeignClients。
package com.example.user;
import com.alibaba.nacos.api.annotation.NacosProperties;
import com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig;
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "127.0.0.1:8848"))
//@NacosPropertySource(dataId = "user-dev.yml", groupId = "DEV_GROUP",autoRefreshed = true)
@RefreshScope
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
这是一个简单的搭建思路。其中nacos不懂的需要下去学习学习。主要是maven的统一管理。cloud 的一些yml配置。