目录
什么是单体架构
传统架构。集所有功能于一身构建一个项目,不可分开部署
什么是微服务架构
微服务架构就是将单个应用程序分成多个应用程序,这多个应用程序就成为了微服务。每个微服务运行在自己的进程中,并使用轻量级的机制通讯,这些服务围绕业务能力来划分,并且自动化部署机制来独立部署,这些服务可以使用不同的编程语言,不同数据库,以保证最低限度的集中式管理。
什么是分布式架构
分布式的核心就一个字:拆。只要是将一个项目拆分成了多个模块,并将这些模块分开部署,那就算是分布式。
如何拆呢?有两种方式:水平拆分,或垂直拆分(也称为“横向拆分”和“垂直拆分”)
水平拆分:根据“分层”的思想进行拆分。例如,可以将一个项目根据“三层架构”拆分成 表示层(jsp+servlet)、业务逻辑层(service)和数据访问层(dao),然后再分开部署:把表示层部署在服务器A上,把service和dao层部署在服务器B上,然后服务器A和服务器B之间通过dubbo等RPC进行进行整合
垂直拆分:根据业务进行拆分。例如:可以根据业务逻辑,将“电商项目”拆分成“订单项目”、“用户项目”和“秒杀项目”。显然这三个拆分后的项目,仍然可以作为独立的项目使用。像这种拆分的方法,就成为垂直拆分。
总结:
分布式:拆了就行。
微服务:细粒度的垂直拆分。
简介
SpringCloud为开发人员提供工具,以快速构建分布式服务系统中某些常见模式。(例如:配置管理、服务注册发现、智能路由、控制总线、全局锁、分布式会话、集群状态等)
SpringCloud体系
spring--------->--------------------->springboot---------------->springCloud
spring以bean对象为中心,提供了IOC、AOP 等功能。
springBoot以Application应用为中心,提供了自动配置、监控等功能。
springCloud以Server服务为空心,提供服务的注册与发现、服务的调用与负载均衡等功能。
springClond模块介绍
EureKa 服务注册与发现
Ribbon 客户端的负载均衡组件。
Hystrix 熔断器,能够防止服务的雪崩效应。
Feign web服务客户端,能够简化Http接口调用。
Zull 网关,提供路由转发、请求过滤等功能。
Config 分布式配置管理。
Sleuth 服务跟踪。
Stram 构建消息驱动的微服务应用程序框架。
Bus 消息代理集群消息总线。
Alibaba 最新组件
Sentinel 把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Nacos 动态服务发现、配置管理
Seata 阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。
Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务
Dubbo Apache Dubbo™ 是一款高性能 Java RPC 框架。
SkyWalking 分布式链路追踪与监控系统
一步步搭建参考:Spring Cloud Alibaba 实战(一)准备篇 - 掘金
组件使用
EureKa使用举例
常用服务注册发现组件还有Zookeeper、Consul、Nacos
Eureka包含2个组件:Eureka Server和Eureka Client
服务启动后会向Eureka Server发送心跳,默认每隔30s进行续约自己的信息;
Eureka Server在一定时间内没有收到心跳,默认为90s,则Eureka Server会注销掉自己该服务节点;
Eureka Client每次调用服务都会缓存Eureka Server信息,当Eureka Server发生宕机时,服务依旧可以被调用。
1.以maven工程为例,先在pom.xml引用jar
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.5.0</version>
</dependency>
2.然后我们去yml文件中做如下配置
#eureka的端口号
server:
port: 8888
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
3.在启动类里添加表示为eureka注册中心
@EnableEurekaServer
@SpringBootApplication
public class LearningApplication {
public static void main(String[] args) {
SpringApplication.run(LearningApplication.class, args);
}
}
zuul组件
路由转发、API监控、权限校验、限流。
1. 现在pom.xml 中,加入如下依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
2.创建Application启动类,并增加EnableZuulProxy注解
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3. 最后添加 application.yml 配置文件,内容如下:
server:
port: 8080
spring:
application:
name: gateway
zuul:
routes:
api:
path: /api/**
serviceId: eurekaclient
zuul.routes.api.path:指定请求基础地址,其中api可以任何字符。
serviceId : 转发到服务ID,也就是指定服务的application.name,上述实例的含义表示只要包含/api/的地址,都自动转发到eurekaClient的服务去。
创建Zuul过滤器
/**
* @Author:air
* @create 2022-06-30
*
* 编辑ZuulFilter自定义过滤器,用于校验登录
* 重写zuulFilter类,有四个重要的方法
* 1.shouldFilter:返回一个Boolean值,判断该过滤器是否需要执行。返回true执行,返回false不执
* 行。
* 2.run:过滤器的具体业务逻辑。
* 3.filterType:返回字符串,代表过滤器的类型。包含以下4种:
* pre:请求在被路由之前执行
* routing:在路由请求时调用
* post:在routing和errror过滤器之后调用
* error:处理请求时发生错误调用
* 4.filterOrder:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高
*/
@Component
public class LoginFilter extends ZuulFilter {
@Override
public String filterType() {
// 登录校验的过滤级别,肯定是第一层过滤
return "pre";
}
@Override
public int filterOrder() {
// 执行顺序为1,值越小执行顺行越靠前
return 1;
}
@Override
public boolean shouldFilter() {
// 默认此类过滤器时false,不开启的,需要改为true
return true;
}
/**
* 登录校验过滤器,执行逻辑的方法
* @return
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
// 登录校验逻辑
// 1)获取zuul提供的请求上下文对象(即是请求全部内容)
RequestContext currentContext = RequestContext.getCurrentContext();
// 2) 从上下文中获取request对象
HttpServletRequest request = currentContext.getRequest();
// 3) 从请求中获取token
String token = request.getParameter("access-token");
// 4) 判断(如果没有token,认为用户还没有登录,返回401状态码)
if(token == null || "".equals(token.trim())){
// 没有token,认为登录校验失败,进行拦截
currentContext.setSendZuulResponse(false);
// 返回401状态码。也可以考虑重定向到登录页
currentContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
}
// 如果校验通过,可以考虑吧用户信息放入上下文,继续向后执行
return null;
}
}