SpringCloud
微服务定义
- 是一种架构风格
- 一系列微小的服务共同组成
- 每个服务跑在自己的进程里
- 每个服务为独立的业务开发
- 独立部署
- 分布式的管理
架构形态
单体架构
特点:
- 打包成一个war包,没有外部依赖
- 共用一个db
- 容易测试
- 容易部署
- 开发效率低
- 代码维护困难
- 部署不够灵活
- 构建时间特别长
- 稳定性不高
- 扩展性不够,不能满足高并发需求
基于ajax的前后端分离
分布式架构
定义:支持应用程序和服务的开发,可以利用物理架构和多个自制的处理元素(多节点),不共享主内存,但通过网络发送消息
简单的微服务
基础框架组件
服务注册发现
服务网关
- 连接内外大门
- 屏蔽后台细节,让用户无感知
- 路由功能,外部请求反向路由到内部某个服务
- 网关功能,控制流量,监控和日志
- 用户认证
- 授权
- 服务网关
前端服务(边缘服务)
聚合
把两个接口聚合在一起返回出去
裁剪
通过不同需求返回不同数据,pc和手机端淘宝返回详情数据不一致
后端通用服务(中间层服务)
阿里系
Dubbo
Zookeeper
Spring MVC or SpringBoot
Spring Cloud
定义
- 是一个开发工具集
- 利用spring boot的开发遍历
- 基于对netflix 开源组件的进一步封装
- 简化了分布式开发
来源
基于Netflix Eureka做了二次封装
文档
http://projects.spring.io/spring-cloud/
版本查看
Eureka Server(注册中心)
-Dserver.port=
pom文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
配置方式
eureka:
client:
service-url:
defaultZone: http://localhost:8080/eureka/
# 不把自己注册到注册中心
register-with-eureka: false
# 设置应用名
spring:
application:
name: eureka
打包
mvn clean package install
Eureka Client(服务注册)
pom文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
yml配置方式
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
# 不把自己注册到注册中心
register-with-eureka: false
#关闭心跳监测
server:
enable-self-preservation: false
# 设置应用名
spring:
application:
name: eureka
server:
port: 8761
开启注解
@EnableDiscoveryClient
和@EnableEurekaClient
区别
如果注册中心是eureka那么推荐使用EnableEurekaClient`
如果是其他注册中心那么推荐使用Enable
Eureka的高可用
两个eureka都能看到client的信息
如果一个client挂掉了那么两个eureka都没有信息
解决:
多台
分布式中为什么需要服务发现
a和b沟通完全通过注册中心
服务端发现
- Nginx
- Zookeeper
- Kubernetes
客户端发现
- Eureka
微服务的特点
- 异构
- 不同类型的数据库
- Spring Cloud通过rest方式实现服务注册
- Node.js的eureka-js-client
服务拆分方法
- 分清楚起点和终点
- 了解现有架构是否支持微服务架构
- 架构是不断引进的
不适合微服务的系统
- 系统中包含很多强事物场景的
- 业务相对稳定,迭代周期长
- 访问压力不大,可用性要求不高
康威定律
任何组织在设计一套系统时,所交互的设计方案在结构上都与该组织的沟通结构保持一直
微服务特点
- 一系列微小的服务共同组成
- 单独部署,跑在自己的进程里
- 每个服务为独立的业务开发
- 分布式的管理
扩展立方模型
- X轴 水平复制
- Y轴功能解耦
- 单一职责,每个服务负责单一功能
- 相关功能聚集在一个服务内
- 关注点分离
- 职责分离
- 通用性分离
- 基础组件划分
- 消息服务
- 用户服务
- 公共组件拆分
- 粒度分离
- 不是越小越好
- Z轴 数据分区
点餐业务拆分
拆分服务
服务拆分方法论
- 每个微服务都有单独的数据存储
- 依据服务特点选择不同结构的数据库类型
- 搜索->elasticsearch
- 订单类-》mysql
- 难点在难以确定边界
- 针对边界设置api
- 依据边界权衡数据冗余
应用通信
调用的三种方式
-
直接使用RestTemplate
-
String s = restTemplate.getForObject("http://localhost:8083/hello", String.class);
-
-
使用LoadbalanceClient
-
ServiceInstance serviceInstance = loadBalancerClient.choose("PRODUCT"); String url = String.format("http://%s:%s", serviceInstance.getHost(), serviceInstance.getPort() + "/hello"); String result = restTemplate.getForObject(url, String.class);
-
-
使用注解
-
@Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); }
-
客户端负载均衡器(Ribbon)
- RestTemplate
- Feign
- Zuul
发现方式
- 服务发现
- 服务选择规则
- 服务监听
主要组件
- ServerList
- IRule
- ServerListFilter
源码解析
-
-
-
-
用来获取所有列表
-
轮循策略默认是roundRobinRule
修改默认轮询策略
-
http://cloud.spring.io/spring-cloud-static/Finchley.M2/#loadbalanced-webclient
users: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule
-
轮循策略
-
Feign使用(内部也使用了rabbion做负载均衡)
-
Pom文件
-
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency>
-
-
启动主类增加注解
@FeignClient
-
编写接口
-
@FeignClient("product") public interface FeignConfig { @GetMapping("hello") String hello(); }
-
-
注入和调用
-
@Autowired private FeignConfig feignConfig; @RequestMapping("/feign") public String feign() { String result = feignConfig.hello(); return result; }
-
多模块拆分服务
问题
- 商品和订单dto重复定义
- 同一个对象多次重复定义
- 订单服务里面不应该知道商品服务的uri
模块拆分
- product-server
- 业务逻辑
- product-client
- 对外暴露的接口
- Product-common
- 公用的对象
- 依赖关系
打包命令
mvn -Dmaven.test.skip=true -U clean install
同步还是异步
- 消费者通过消息中间件进行解耦
- 用户调用短信服务,积分服务,其他服务,服务耦合过大,用户登录成功需要多个服务同步响应后才告诉成功
- 商品服务库存变化发布消息,订单服务订阅消息,比如商品信息
- 订单不需要查询商品服务而是查询自己服务中的信息
- 保证数据最终一致性,只需要订阅对应服务就能保证
- 商品服务库存变化发布消息,订单服务订阅消息,比如商品信息
- 常见消息队列
- RabbitMQ
- Kafka
- ActiveMQ
RabbitMQ安装
5672->默认RabbitMQServer端口
15672->RabbitMQ管理页面端口,页面只需要配置这个
docker run -d --hostname my-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3.7.3-management
默认密码:guest
Docker和DevOps
- docker能够解决不同环境下应用程序都能运行
- 轻量
- 进程隔离和管理
- 可复用,版本化(tag机制)
- 微服务架构师核心,devops和docker是手段