1.微服务是一种架构思想
1.1用好微服务要解决四个问题
- 这么多服务,客户端怎么访问?
- 这么多服务,服务之间如何通信呢?
- 这么多服务,如何治理呢?
- 这么多服务,服务挂了怎么办?
参考:
https://springcloud.cc/spring-cloud-netflix.html
中文API文档:https://springcloud.cc/spring-cloud-dalston.html
SpringCloud中国社区 http://springcloud.cn/
SpringCloud中文网 https://springcloud.cc
1.1.1、SpringCloud Netflix 一站式解决方案,上面的四个核心问题,他都可以解决!
api网关 — zuul
通信 ---- Feign-- HttpClient – Http的通信方式,同步并阻塞的
服务注册与发现 — Eureka
熔断机制 — Hystrix
2018年底、Netflix宣布了无限期停止维护,生态不再维护,可能会有安全隐患
1.1.2
Apache Dubbo + Zookeeper
api网关:没有… 借用别人的,或者自己开发
Dubbo: 基于Java 的高性能的Rpc通信框架 - Rpc, 异步非阻塞
服务注册与发现 Zookeeper (动物园管理者,Hadoop、Hive…)
熔断机制 没有, 借助 Hystrix
1.1.3
SpringCloud Alibaba 一站式解决方案,上面的四个核心问题,他都可以解决
本质:
1、API网关,服务路由
2、HTTP、RPC 通信方式 服务调用
3、服务注册与发现, 高可用
4、熔断机制,服务降级
2.springcloud–eureka
Eureka 是 Netlix的 一个组件, 遵循 AP 原则 (CAP)
C 一致性
A 可用性
P 分区容错性 (必要)
Eureka 是一个基于 Rest的服务,用于定位服务,实现云端的故障转移。
商店:注册中心 , 进货(服务提供者提供的),你(消费者进去可以根据自己的选择来购买)
对比dubbo
Eureka 包含两个组件 : Server。 Client
1、服务端启动!
2、Client 就是一个 Java 客户端,可以和 Server 交互,客户端内置 负载均衡的算法。
规则:
注册中心,登记我们的服务,定期检测我们的服务有没有挂!(心跳检测,我发送一个请求,有没有回 应!)
Client 启动之后,会定期给 Server 发送心跳 (30s)。
Server 长时间没有接收到心跳,他就会认为这个服务挂了,就会移出注册中心 !
使用eureka四部
1.导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
2.编写配置
server:
port: 7001
eureka:
instance:
hostname: localhost #实例名称
client:
fetch-registry: false # 不需要检索自己
register-with-eureka: false # 是否将自己注册到注册中心
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
3.编写启动类
@SpringBootApplication
@EnableEurekaServer
public class EurekaServer7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaServer7001.class,args);
}
}
启动失败
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
java.lang.invoke.MethodHandleNatives.resolve(Native Method)
The following method did not exist:
com.google.gson.GsonBuilder.setLenient()Lcom/google/gson/GsonBuilder;
The method's class, com.google.gson.GsonBuilder, is available from the following locations:
jar:file:/D:/sheng/ruanjian/apache-maven-3.3.9/repo1/com/google/code/gson/gson/2.1/gson-2.1.jar!/com/google/gson/GsonBuilder.class
It was loaded from the following location:
file:/D:/sheng/ruanjian/apache-maven-3.3.9/repo1/com/google/code/gson/gson/2.1/gson-2.1.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of com.google.gson.GsonBuilder
添加依赖
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
4.测试
3.提供者
1.导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
2.编写配置
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis-config.xml
type-aliases-package: com.sheng.pojo
mapper-locations:
- classpath:mybatis/mapper/**/*.xml
spring:
application:
name: springcloud-provider-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: org.gjt.mm.mysql.Driver
url: jdbc:mysql://localhost:3306/springcloud01
username: root
password: root
dbcp2: # 连接池配置
min-idle: 5
initial-size: 5
max-total: 5
max-wait-millis: 200
# Eureka
eureka:
client:
service-url:
defaultZone:http://localhost:7001/eureka/
3.启动类添加注释
@SpringBootApplication
@EnableEurekaClient
public class DeptProvider8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvider8001.class,args);
}
}
4.测试
<properties>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.18.12</lombok.version>
</properties>
<!-- 只做管理,不下载依赖 -->
<dependencyManagement>
<dependencies>
<!-- spring-cloud的依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring-boot-dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- mysql 5 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<!-- mybatis -->
<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>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
完善信息
导入依赖 父工程有版本控制
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置文件加入info配置
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis-config.xml
type-aliases-package: com.sheng.pojo
mapper-locations:
- classpath:mybatis/mapper/**/*.xml
spring:
application:
name: springcloud-provider-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: org.gjt.mm.mysql.Driver
url: jdbc:mysql://localhost:3306/springcloud01
username: root
password: root
dbcp2: # 连接池配置
min-idle: 5
initial-size: 5
max-total: 5
max-wait-millis: 200
# Eureka
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
instance-id: 服务提供者
info:
app.name: sheng的微服务提供者8001
company.name: 公司名
build.artifactId: ${project.artifactId}
build.version: ${project.version}
4.模拟集群
1.配置域名解析
2.编写3个微服务
3.配置文件
server:
port: 7001
eureka:
instance:
hostname: localhost #实例名称
client:
fetch-registry: false # 不需要检索自己
register-with-eureka: false # 是否将自己注册到注册中心
service-url:
defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
server:
port: 7002
eureka:
instance:
hostname: localhost #实例名称
client:
fetch-registry: false # 不需要检索自己
register-with-eureka: false # 是否将自己注册到注册中心
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/
提供者配置
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis-config.xml
type-aliases-package: com.sheng.pojo
mapper-locations:
- classpath:mybatis/mapper/**/*.xml
spring:
application:
name: springcloud-provider-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: org.gjt.mm.mysql.Driver
url: jdbc:mysql://localhost:3306/springcloud01
username: root
password: root
dbcp2: # 连接池配置
min-idle: 5
initial-size: 5
max-total: 5
max-wait-millis: 200
# Eureka
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/
instance:
instance-id: 服务提供者
info:
app.name: sheng的微服务提供者8001
company.name: 公司名
build.artifactId: ${project.artifactId}
build.version: ${project.version}
4.测试
5.Ribbon
Spring Cloud Ribbon 是一套客户端的负载均衡工具
主要功能就是提供客户端软件负载均衡算法。连接超时、重试
负载均衡:将用户的请求均摊的分配到多个服务器上,从而达到 HA (高可用
软件: nginx LvsM
Dubbo、SpringCloud均给我们提供了负载均衡能力!SpringCloud负载均衡算法可以自定义!
负载均衡的简单分类
- 集中式LB
服务消费方和服务提供者之间,单独设置一个设施!
比如Nginx - 进程式LB
将LB 集成到 消费方,消费方从服务注册中心中获知有哪些可用的地址,这个时候从中选取一 个合适的服务器
Ribbon 就是属于进程内的 LB、集成到我们的客户端中就可以
ribbon使用
1.导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
2.配置文件
server:
port: 80
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/
3.80项目下配置类添加注解
@Configuration
public class ConfigBean {
@Bean
@LoadBalanced // SpringCloud Ribbon 是基于客户端实现的一套负载均衡的工具
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
4.主启动类
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableEurekaClient //客户端
public class DeptConsumer80 {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer80.class,args);
}
}
controller
@RestController
public class DeptConsumerController {
@Autowired
private RestTemplate restTemplate;
// http://localhost:8001
private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT"; //对应配置文件
@RequestMapping("consumer/add")
public boolean add(@RequestBody Dept dept){
return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add",dept,Boolean.class);
}
@RequestMapping("consumer/list")
public List<Dept> list(){
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list",List.class);
}
@RequestMapping("consumer/findById/{id}")
public Dept findById(@PathVariable("id") Long id){
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id,Dept.class);
}
}
5.测试
需要添加拷贝8001 8002 8003
server:
port: 8002
mybatis:
config-location: classpath:mybatis/mybatis-config.xml
type-aliases-package: com.sheng.pojo
mapper-locations:
- classpath:mybatis/mapper/**/*.xml
spring:
application:
name: springcloud-provider-dept #名字必须一致
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: org.gjt.mm.mysql.Driver
url: jdbc:mysql://localhost:3306/springboot #更换数据库
username: root
password: root
dbcp2: # 连接池配置
min-idle: 5
initial-size: 5
max-total: 5
max-wait-millis: 200
# Eureka
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/
instance:
instance-id: 服务提供者8002 #名字对应
info:
app.name: sheng的微服务提供者8002
company.name: 公司名
build.artifactId: ${project.artifactId}
build.version: ${project.version}
Riboon其实就是一个软负载均衡的客户端组件,他可以和其他所有需要请求的客户端结合使用。
默认的负载均衡算法就是我们的轮询
Ribbon的核心组件 IRule