Java_微服务

news2024/11/14 20:34:20

        首先介绍一下单体架构与微服务架构:

单体架构:

微服务:

SpringCloud:

版本:

        标黑部分为目前企业使用最多的版本,因为它支持jdk8、jdk11,下面使用SpringCloud也会使用这个版本。

服务拆分:

拆分原则:

什么时候拆分?

怎么拆分?

工程结构:

拆分后的工程结构有两种:

        1.独立Project,将拆分后的所有服务放到一个文件夹中,适合大型项目(有很多微服务)。

        2.Maven聚合,创建一个Project,然后在其下面创建Module为微服务模块。

        

        服务拆分后,不同微服务之间可能有调用,比如购物车服务中会调用到商品服务,那么需要进行远程调用。

远程调用:

1.方法一:(不推荐)

        就可以利用RestTemplate在购物车服务中向商品服务发送http请求并获取响应体。

问题:

        为了减小服务压力,http请求接收的服务可能会部署多个,所以并不能确定向哪个服务发送http请求。

2.方法二:

注册中心:
原理:

Nacos注册中心:

        Nacos是目前国内企业中占比最多的注册中心组件。它是阿里巴巴的产品,目前以及假如SpringCloudAlibaba中。

        使用时需要首先进行数据库中nacos数据库创建,并且向数据库中导入信息,并启动nacos镜像。

服务注册:

服务发现:

3.OpenFeign(推荐):

使用步骤:

        注意:因为OpenFeign底层发送http请求是通过Client发送的,而Client每一次发送都需要重新创建连接,所以效率很低,因为我们使用连接池优化

连接池:

连接池使用:

实践方案:

方案一:(较推荐)

特点:

        代码结构更合理,耦合度非常低,但是项目结构变复杂。

方案二:

特点:

        结构更简单,使用更方便,但代码耦合度更高一点。

定义的FeignClient不在扫描包范围时:

日志:

网关:

        网关就是网络的关口,负责请求的路由、转发、身份校验。

SpringCloud中的网关的实现:

        这里我们使用Spring Cloud Gateway。

快速入门

路由属性:


路由断言:

路由过滤器:

        如果想要给所有服务都配置一种路由过滤器,可以在与routes同级的位置配置default-filters,然后输入要配置的路由过滤器。

网关请求处理流程:

        因此,我们要在网关内进行登录校验,需要自定义pre的过滤器进行jwt校验。

自定义过滤器:

自定义GlobalFilter:(大多数情况)
参数:

步骤:

        可以实现Ordered接口,就能够定义过滤器优先级。

自定义GatewayFilter

实现登录校验:

        我们可以在网关中通过自定义过滤器实现登录校验

实现网关传递用户信息:

网关保存用户到请求头:

完整代码:
@Component
@RequiredArgsConstructor
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    private final AuthProperties authProperties;

    private final JwtTool jwtTool;

    private final AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1.获取request
        ServerHttpRequest request = exchange.getRequest();
        //2.判断是否需要做登录拦截
        String path = request.getPath().toString();
        if (isExclude(path)) {
            return chain.filter(exchange);
        }
        //3.获取token
        String token = null;
        HttpHeaders headers = request.getHeaders();
        List<String> authorization = headers.get("Authorization");
        if (authorization != null && authorization.size() > 0) {
            token = authorization.get(0);
        }
        //4.校验并解析token
        Long userId = null;
        try {
            userId = jwtTool.parseToken(token);
        } catch (UnauthorizedException e) {
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        //5.传递用户信息
        String userInfo = userId.toString();
        ServerWebExchange swe = exchange.mutate()
                .request(builder -> builder.header("user-info", userInfo))
                .build();
        //6.放行
        return chain.filter(swe);
    }

    private boolean isExclude(String path) {
        List<String> excludePaths = authProperties.getExcludePaths();
        for (String pathPattern : excludePaths) {
            if (antPathMatcher.match(pathPattern, path)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

        antPathMather是一个路径字符匹配器API,它可以方便我们对路径进行匹配。

编写SpringMVC拦截器

        编写拦截器以获取登录用户

步骤:
1.首先编写拦截器类:

        需要让拦截器实现HandlerInterceptor接口,重写preHandle和afterCompletion方法,preHandle是在传给后续微服务前执行,所以在这个方法中将用户信息存入ThreadLocal。afterCompletion是在使用完后执行,所以删除存储的用户信息,防止内存泄漏。

public class UserInfoInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1.获取用户信息
        String userInfo = request.getHeader("user-info");
        //2.判断是否为空,不为空则存入ThreadLocal
        if(StrUtil.isNotBlank(userInfo)) {
            UserContext.setUser(Long.parseLong(userInfo));
        }
        //3.放行
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserContext.removeUser();
    }
}
2.编写配置类

        编写完拦截器后,需要在编写配置类使之生效

        需要注意的有

                ·配置类注解@Configuration表名它是一个配置类

                ·注解@ConditionalOnClass,是为了让网关不接收这个拦截器,让其他微服务接收,注解实现让具有DispatcherServlet.class的微服务接收拦截器,这是SpringMVC特有的class对象,网关中没有配置SpringMVC所以网关就不会接收。

                ·因为是SpringMVC中的拦截器,配置类要继承WebMvcConfigurer接口,并实现addInterceptors方法,添加刚刚编写的拦截器。

@Configuration
@ConditionalOnClass(DispatcherServlet.class)
public class MvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new UserInfoInterceptor());
    }
}
3.将配置类放入SpringBoot配置文件中:

        将配置类全类名放入spring.factories配置文件中

实现微服务之间传递用户信息:

        可以使用OpenFeign实现

在Feign的配置类中直接定义拦截器:

public class DefaultFeignConfig {
    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }

    @Bean
    public RequestInterceptor userInfoRequestInterceptor() {
        return new RequestInterceptor() {
            @Override
            public void apply(RequestTemplate requestTemplate) {
                Long userId = UserContext.getUser();
                if (userId != null) {
                    requestTemplate.header("user-info", userId.toString());
                }
            }
        };
    }
}

注意微服务启动类上要有注解:

@EnableFeignClients(basePackages = "com.hmall.api.client", defaultConfiguration = DefaultFeignConfig.class)

总结:

配置管理:

共享配置:

为什么要使用配置管理:

使用配置管理服务:

        我们在服务远程调用时使用的注册中心Nacos,就有配置管理服务的功能

1.添加配置到Nacos:

        添加微服务中共享的那部分配置即可。

        注意可以使用变量,即${配置文件中的路径},在原yml配置文件中配置变量,即可正常读取。

2.拉取共享配置

①引入依赖

②新建bootstrap.yaml

        在微服务中创建bootstrap.yaml配置文件,在bootstrap.yaml中配置的信息不需要再配置了。

配置热更新:

        配置热更新:当修改配置文件中的配置时,微服务无需重启即可使配置生效。

前提条件:

步骤

1.在nacos中定义一个与微服务名有关的配置文件

在上述bootstrap.yaml中已经有了这部分信息

2.加载属性

        一般采用这种方式:

        

        完成后,在nacos中配置一旦变更,就会实时更新。

服务保护和分布式事务:

雪崩问题:

        雪崩问题是服务保护方面经常碰到的一个问题,即:

        微服务中调用链路中的某个服务故障,引起整个链路中的所有微服务都不可用,这就是雪崩

产生原因:

解决思路:

服务保护方案:

请求限流:

线程隔离:

服务熔断:

解决方案总结:

服务保护技术:

        我们可以使用服务保护技术方便我们完成上述解决方案。

Sentinel:

Sentinel是阿里巴巴开源的一款微服务流量控制组件。官网地址:home | Sentinel (sentinelguard.io)

簇点链路介绍:

使用方法:

引入依赖:

<!--sentinel-->
<dependency>
    <groupId>com.alibaba.cloud</groupId> 
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

配置控制台:

spring
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8090
      http-method-specify: true #是否设置请求方式作为资源名称
请求限流:

        在簇点链路后面点击流控按钮,即可对其做限流配置:

        点击后弹出下面的窗口:

        阈值类型默认为QPS,即每秒请求的数量,在单机阈值处填写数据点击新增即可。

线程隔离:

        线程隔离也是要点击流控按钮,在窗口中配置并发线程数

Fallback:

        实现Fallback要对FeignClient操作,所以需要让它成为Sentinel的簇点资源。

编写步骤:

步骤一:

        在编写的cilent包下新建fallback包再新建FallbackFactory类即可。

步骤二:

步骤三:

服务熔断:

        服务熔断通过断路器实现。

断路器原理:

使用方法:

        点击簇点链路的熔断按钮,弹出下面窗口,默认选取的是慢调用比例,最大RT(response time)即最大响应时间,超过整个响应时间的请求被归为慢调用,比例阈值就是当慢调用的请求的比例超过比例阈值时,就会进行熔断,最小请求数量就是要对这么多次的请求一起判断,统计时长就是统计的周期。

分布式事务:

        分布式事务调用了其他服务,举例:

        如果不解决分布式事务,当程序正常进行,但是到第三步扣减商品库存出现问题,比如库存不足报错,这时库存没有正常扣减,但是购物车已经被清除,没有保证原子性。

        注意这种情况不能使用@Transactional注解,它只适用于单个服务。

解决思路:

        各个子事务之间必须能感知到批次的事务状态,才能保证状态一致。

Seata:

        它本身也是一个微服务。

架构:

使用步骤:
建表:

        Seata支持多种存储模式,但考虑到持久化的需要,我们一般选择基于数据库存储。

准备配置文件:

        将seata的配置文件放入服务器或虚拟机/root目录下

用docker部署:

        需要注意,要确保nacos、mysql都在hm-net网络中。

微服务整合Seata:

首先需要引入依赖:

<!--统一配置管理-->
  <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  </dependency>
  <!--读取bootstrap文件-->
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-bootstrap</artifactId>
  </dependency>
  <!--seata-->
  <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
  </dependency>

        我将它定义在了nacos共享配置中。

最后,新建bootstrap.yaml文件,定义如下配置

spring:
  application:
    name: ****-service # 服务名称
  profiles:
    active: dev
  cloud:
    nacos:
      server-addr: ***.***.***.*** # nacos地址
      config:
        file-extension: yaml # 文件后缀名
        shared-configs: # 共享配置
          - dataId: shared-seata.yaml # 共享seata配置
Seata模式:
XA模式:

优点:

缺点:

实现:

AT模式:

实现:

XA模式与AT模式的区别:

(即XA模式在整个过程中数据库中的信息都是一致的,而AT模式在一阶段提交完成后,有服务出现问题,在二阶段根据数据快照恢复数据前,会出现短暂的数据不一致情况)

后续学习:

RabbitMQ:

        详见作者的下一篇文章:Java_RabbitMQ

Elasticsearch(ES):

        详见作者的下下篇文章:Java_Elasticsearch(ES)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1966489.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot校园商店配送系统-计算机毕业设计源码68448

摘要 本文详细阐述了基于Spring Boot框架的校园商店配送系统的设计与实现过程。该系统针对校园内的用户需求&#xff0c;整合了用户注册与登录、商品浏览与购买、订单管理、配送追踪、用户反馈收集以及后台管理等功能&#xff0c;为校园内的普通用户、商家、配送员和管理员提供…

今年考研报名时间确定了!(内涵西电考研报名流程)

虽然初试时间还没有得到正式官宣&#xff0c;但是再过1个多月&#xff0c;考研人们最近的一件大事——预报名就要来啦&#xff01; ⏰预报名时间 9月24日至9月27日&#xff0c;每天9:00—22:00&#xff1b; ⏰正式报名时间 10月8日至10月25日&#xff0c;每天9:00—22:00。 …

数据开发/数仓工程师上手指南(五)CDM-DIM层搭建规范及流程

前言 在上篇文章的进度和基础之上&#xff0c;我们已经算是构建好了ODS数据引入层&#xff0c;ODS这一层构建的比较简单&#xff0c;没有很多限制规范&#xff0c;但是CDM数据公共层可以算得上是数据仓库的主题&#xff0c;之前我们也将DWD数据明细层、DIM数据维度层和DWS公共…

【C++标准库】模拟实现string类(深浅拷贝问题)

模拟实现string类 一.命名空间与类成员变量二.构造函数1.无参&#xff08;默认&#xff09;构造2.有参构造3.兼容无参和有参构造4.拷贝构造1.传统写法2.现代写法 三.析构函数四.string类对象的容量操作1.size2.capacity3.clear4.empty5.reserve6.resize 五.string类对象的访问及…

Redis学习[4] ——Redis集群

五、Redis 集群 5.1 什么是Redis集群&#xff1f; 如何提供一个高可用的Redis服务&#xff1f; —— 构建Redis集群 单服务器Redis由于数据都是存储在一台服务器&#xff0c;如果这台服务器出现宕机或者故障&#xff0c;可能会导致服务不可用甚至数据丢失。 要避免这种单点…

C#使用NPOI进行Excel和Word文件处理(一)

文章目录 前言文件大小性能NPOI 的优势示例代码性能优化建议总结Github 地址链接导出效果 前言 NPOI 是一个非常流行的用于在 .NET 环境中操作 Office 文件&#xff08;包括 Excel 文件&#xff09;的开源库。它的功能非常强大&#xff0c;但性能和文件大小问题可能因具体的使…

“八股文”面试题:是招聘程序员的金科玉律?

引言 随着互联网的发展&#xff0c;现代企业对程序员的需求日益增加。在招聘过程中&#xff0c;许多公司采用了“八股文”式的面试题目来筛选候选人。这些题目往往涵盖了算法、数据结构、系统设计等方面的基础知识。然而&#xff0c;对于“八股文”在实际工作中的作用&#xf…

安泰高压放大器在材料极化中的应用有哪些

高压放大器在材料极化中具有重要的应用&#xff0c;这方面是通过在材料中施加高电压来实现的。下面我们将探讨高压放大器在材料极化领域的具体应用&#xff0c;以及其在材料科学和工程中的重要性。 首先&#xff0c;让我们了解一下材料极化的基本概念。材料的极化是指在外加电场…

气象水文耦合模式WRF-Hydro安装、数据制备、代码编译、离线在线运行

目录 专题一 WRF-Hydro模型功能及运行流程、依赖库准备 专题二 WRF-Hydro模式编译、离线运行及案例实践 专题三 结合多案例进行模式数据制备及实践应用 专题四 WRF-Hydro模式耦合编译及运行、总结 更多应用 WRF-Hydro模型是一个分布式水文模型&#xff0c;‌它基于WRF‌陆…

视角 | 麻省理工学院提出出温度计校准法,专治AI大模型过度自信

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

使用Python自动将照片文件夹转换为PowerPoint幻灯片

在这个数字时代,我们经常需要快速创建照片幻灯片来展示我们的回忆或工作成果。今天,我们将探讨如何使用Python来自动化这个过程,将一个文件夹中的所有照片转换为一个精美的PowerPoint演示文稿,每张照片占据一页,并以文件名作为标题。 C:\pythoncode\new\jpeginsertppt.py 全部…

【Python 逆向滑块】(实战二)逆向滑块,并实现用Python+Node.js 生成滑块、识别滑块、验证滑块、发送短信

逆向日期&#xff1a;2024.07.31 使用工具&#xff1a;Node.js、油猴 本章知识&#xff1a;逆向网易易盾【fp】参数 文章难度&#xff1a;中等&#xff08;没耐心的请离开&#xff09; 文章全程已做去敏处理&#xff01;&#xff01;&#xff01; 【需要做的可联系我】 AES解…

配电盘emc测试技术咨询

申请配电盘 EMC 测试技术咨询的费用因机构、测试项目和服务内容的不同而有所差异。一般来说&#xff0c;测试机构会根据测试项目的复杂程度、测试时间和场地等因素来确定费用。 影响配电盘 EMC 测试技术咨询办理费用的因素有很多&#xff0c;其中主要的因素有&#xff1a; 1、检…

windows 环境测试使用 Visual Studio 2022 MSVC 自带的 cl + nmake 版本的 Makefile 编译代码

前言&#xff1a; windows 环境的 cl 和 nmake 就相当于 Linux 环境的 gcc、g 和 make&#xff1b;linux 中可以在 Makefile 中写 gcc、g 语句&#xff0c;然后执行 make&#xff1b;同样的&#xff0c;在 windows中也可以新建 Makefile 文件&#xff0c;在里面写 cl 语句&…

基于springboot+vue+uniapp的养老院管理系统小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

45.二维数组练习:计算季度营业额和年总营业额

/* 某商场每个季度营业额如下,单位&#xff1a;万元 第一季度&#xff1a;22&#xff0c;66&#xff0c;44 第二季度&#xff1a;77&#xff0c;33&#xff0c;88 第三季度&#xff1a;25&#xff0c;45&#xff0c;65 第四季度&#xff1a;11&#xff0c;66&#xff0c;99 要求…

贵州桐梓影像大赛启动 百名摄影师齐聚桐梓采风创作

夏季的桐梓&#xff0c;山水秀美&#xff0c;天空湛蓝。近日&#xff0c;贵州桐梓首届旅游影像大赛启动&#xff0c;来自全省各地的100余名摄影师共聚一堂&#xff0c;开展一场别具一格的采风创作活动。他们带着镜头&#xff0c;追寻着光影的脚步&#xff0c;捕捉桐梓的自然风光…

使用WebSocket实现log日志流的实时展示-从轮询到通知

场景介绍 最近开发一个系统&#xff0c;其中一个模块需要展示实时的执行过程&#xff0c;过程日志可能比较多。以前的方案都是前端定时轮询&#xff0c;比如每秒查一次后端接口&#xff0c;将拉取回来的日志重新展示。轮询方案简单容易实现&#xff0c;但是比较消耗资源&#…

ctfhub-SQL注入-1-基础题目详解

1.打开题目在url上判断是数字型注入还是字符型注入 1 //无回显&#xff0c;说明是报错了&#xff0c;‘和后面的‘冲突了 1’ -- //有回显&#xff0c;是因为--把后面的‘注释掉了 2.使用命令判断列数 1order by 1-- //有回显 1order by 2 -- //有回显 1order by …

推荐Nodejs下高效存储树到数据库工具库-FlexTree

官网 | English FlexTree是Nodejs下一个基于左右值算法的树结构库&#xff0c;它提供了一种简单的方式来存储和操作树形结构数据。 FlexTree提供了简单而丰富的API让你可以轻松的操作树&#xff0c;如增删改查、遍历、移动、查询等。 主要特性&#xff1a; 基于左右值算法&a…