4.SpringCloud 基本架构

news2024/11/15 16:41:56

1.SpringCloud概述

        Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁,领导选举,分布式会话,集群状态。(用来管理项目)

2.注册中心Eureka

        Spring Cloud Eureka 是对Netflix公司的Eureka的二次封装,它实现了服务治理的功能,Spring Cloud Eureka提供服务端与客户端,服务端即是Eureka服务注册中心,客户端完成微服务向Eureka服务的注册与发现。服务端和客户端均采用Java语言编写。

        服务器将自己的信息(IP、端口号、服务类) 提供给注册中心,然后每个服务器将所有存在注册中心的注册信息保存一份在自己服务器中,从而实现服务器之间的交流

3. 分布式项目搭建

        在一个分布式项目中,通常会采用父项目和子项目的方式来进行模块化开发和管理。父项目用于管理整个项目的共享依赖和配置,而子项目则代表着项目的不同模块或子系统。

3.1 创建父项目

         可以删除父项目中的src,父项目不需要写代码

        在父项目pom.xml中指定打包方式为pom

<packaging>pom</packaging>

3.2 创建子项目

        子项目pom.xml中指定父项目

 <parent>
           <artifactId>springcloud-teach</artifactId>
           <groupId>com.luobei</groupId>
           <version>1.0</version>
</parent>

        父项目pom.xml中指定子项目 

<modules>
            <module>eureka-server</module>
</modules>

        配置yml配置文件

server:
  port: 8081
spring:
  application:
    name: goods   #微服务可以根据微服务的名字自动形成集群,微服务的名字中不要出现下划线
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/    #向这个接口注册
  instance:
    instance-id: goods-8081     #指定当前微服务在注册中心中的id

        主启动类上开启 @EnableEurekaClient

@SpringBootApplication
@EnableEurekaClient
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

3.2.1 创建注册中心

        注册中心其实就是一个特殊的子项目,除yml配置不同,其他与别的子项目一致

server:
  port: 8761
spring:
  application:
    name: eureka-server   #微服务可以根据微服务的名字自动形成集群,微服务的名字中不要出现下划线
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false   #是否将当前服务器注册到注册中心
    fetch-registry: false    #是否将注册列表的信息拉取到本地
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}    
        #注册中心的接口,其他微服务器通过该接口进行注册

        主启动类上开启@EnableEurekaServer

@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

4.微服务调接口

        在微服务架构中,服务之间的通信是通过调用接口来实现的。这些接口可以是 RESTful API、gRPC、消息队列等方式实现的。

4.1 RestTemplate(仅了解)

        属于SpringBoot

        缺点:put、delete请求得不到返回的结果,使用、维护不方便

4.2 openfeign

        OpenFeign 是一个基于 Java 的声明式 HTTP 客户端,通常用于微服务架构中不同服务之间的接口调用。它允许开发者通过注解的方式定义接口,然后由 OpenFeign 自动生成具体的实现。这样可以简化服务之间的通信,让接口调用看起来更像是本地方法调用。

4.2.1 openfeign使用

4.2.1.1 导入依赖

        父项目:

  <dependencyManagement>
    <dependencies>
      <!--openfeign-->
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-openfeign-core</artifactId>
        <version>2.2.6.RELEASE</version>
      </dependency>
    </dependencies>
  </dependencyManagement>

        公共模块:

<!--openfeign-->
<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
      <version>2.2.6.RELEASE</version>
</dependency>

        子项目:

<!--openfeign-->
<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-openfeign-core</artifactId>
</dependency>

4.2.1.2 编写接口

        若接口将会被多个微服务调用则写在commons中

@FeignClient(name="GOODS",path="/goods")
public interface FeignGoodsService {
    @PutMapping("/updateStock")
    ResponseResult<List<Goods>> del(@RequestBody List<OrderGoodsVo> orderGoodsVoList);
}

        @FeignClient(name = "GOODS",path = "/goods") 中name为被调用微服务的名字,path为路径前缀,将要调用的接口方法的声明、请求方式全部拷贝过来

4.2.1.3 使用接口

        在需要使用接口的微服务的主启动类上扫描feign接口

@EnableFeignClients(basePackages = "com.luobei.commons.service")

        然后在需要使用的地方注入就行了

@Resource
private FeignGoodsService feignGoodsService;
@Override
public OrderVo add(Integer uid, AddOrderVo orderVo) throws OutOffStockException {
    ResponseResult<List<Goods>> del = feignGoodsService.del(Arrays.asList(orderGoodsVo));
    return del;
}

4.2.2 openfeign通信日志

        openfeign提供了日志打印功能,通过配置日志级别,对接口的调用情况进行监控和输出

日志级别解释
NONE默认的,不显示任何日志
BASIC仅记录请求方法、URL、响应状态码及执行时间
HEADERS除了 BASIC 中定义的信息之外,还有请求和响应的头信息
FULL除了 HEADERS 中定义的信息之外,还有请求和响应的正文及元数据

        在调用别的服务器的服务器配置配置类

import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class LogConfiguration {
    @Bean
    public Logger.Level level(){
        return Logger.Level.FULL;
    }
}

         因为feign日志的输出级别都是debug级别,还需要设置service包的日志级别

logging:
  level:
    com.commons.service: debug

5. Ribbon负载均衡

        Ribbon是一个基于HTTP和TCP客户端的负载均衡器,默认使用轮询的方式

        SpringCloud Ribbon是基于Netfix Ribbon实现的一套客户端负载均衡工具

5.1 Ribbon配置

5.1.1 全局配置

        在需要调取多个服务器的服务器中配置配置类

@Configuration
public class RibbonConfiguration {

    @Bean
    public IRule rule(){
        return new RandomRule();
    }
}

5.1.2 局部配置

        注意:全局与局部同时存在时,ribbon优先使用全局配置

GOODS:   #微服务名字
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule

5.2 Ribbon超时管理

        Ribbon默认请求超时时间为1000毫秒,有的时候不够用,因此需要重新配置

ribbon:
  http:
    client:
      enabled: true   #开启超时管理
  ReadTimeout: 10000  #请求超时
  ConnectTimeout: 10000 #连接超时

6.网关(Gataway)

        网关是在分布式系统架构中的一种设计模式,用于集中处理和管理请求;微服务架构中常用网关技术有:Zuul、Spring Cloud Gataway等

6.1 网关的作用

        1.路由和负载均衡:网关可以根据请求的路径或其他条件将请求路由到不同的后端微服务

        2.鉴权和认证:网关可以进行用户身份验证、授权以及访问权限的校验

        3.监控和日志:网关可以记录请求和响应的日志,从而监控系统的运行状况、性能和问题

6.2 Zuul

        Zuul 是 Netflix 开源的一个微服务架构中的边缘服务(Edge Service),主要用于实现动态路由、负载均衡、鉴权、监控等功能。(性能不如Gataway)

6.2.1 zuul使用

6.2.1.1 创建zuul微服务

        连接父项目。。

        导入zuul依赖

<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>

6.2.1.2 配置eureka、路由

server:
  port: 8500
spring:
  application:
    name: zuul   #微服务名字,很重要,微服务可以根据微服务的名字自动形成集群,微服务的名字中不要出现下划线
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/    #向这个接口注册
  instance:
    instance-id: zuul-8500     #指定当前微服务在注册中心中的id
zuul:
  routes:
    goods:                 #路由名,用户自定义
      service-id: GOODS    #调用的微服务名
      path: /goods/**      #匹配的路径
    order:
      service-id: ORDER
      path: /order/**
#    GOODS: /goods/**
#    ORDER: /order/**

        注意:路由有两种配置方式,都可

6.2.1.3 zuul主启动类添加注解

@SpringBootApplication
@EnableEurekaClient    //注册
@EnableZuulProxy        //开启路由功能
@EnableHystrix             //解决504报错问题
public class ZuulApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class, args);
    }
}

注意:使用zuul时请求地址应多一个请求的微服务名(http://localhost:8500/goods/goods/all)

 6.2.2 zuul过滤器实现网关限流

zuul过滤器
PRE请求到达zuul之前执行,可以用来鉴权、判断登录、限流
ROUTING

路由时(将请求转发给对应的微服务)执行

POST路由完毕时(微服务返回结果)执行
ERROR在pre、routing、post出现异常时执行

        自定义过滤器使用令牌桶算法实现网关限流

@Slf4j
@Component
public class LimitFilter extends ZuulFilter {

    //创建令牌桶,并设置令牌个数
    private static final RateLimiter RATE_LIMITER = RateLimiter.create(1);

    //指定当前过滤器类型
    @Override
    public String filterType() {
        return "pre";
    }
    //执行顺序,可以为负数,数字越小越先执行
    @Override
    public int filterOrder() {
        return Integer.MIN_VALUE;
    }
    //是否要对当前请求进行过滤
    @Override
    public boolean shouldFilter() {
        //得到请求的uri,判断是否需要登录,如果不需要返回false(放行),否则返回true(执行run()方法)

        //得到上下文对象
        RequestContext context = RequestContext.getCurrentContext();

        HttpServletRequest request = context.getRequest();
        log.info(request.getRequestURI());
        return true;
    }

    //执行过滤业务的代码:例如校验refreshtoken、token
    @Override
    public Object run() throws ZuulException {
        //获取令牌
        if(!RATE_LIMITER.tryAcquire()){
            //令牌用完,至少有100个请求正在处理
            log.info("令牌不足");
            //结束本次请求
            RequestContext context = RequestContext.getCurrentContext();
            context.setSendZuulResponse(false);
            HttpServletResponse response = context.getResponse();
            try {
                response.setContentType("text/html;charset=utf-8");
                response.getWriter().write("系统正忙");
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }
}

6.2.2.1 漏桶算法

        简单来说,把我们的分布式系统理解成一个上方注水下方漏水的桶,固定下方漏水的速率,这样就能限制请求的速度,当水超过桶流量则丢弃

6.2.2.2 令牌桶算法

        每个请求向从桶里获取一个令牌,若令牌没有了则拒绝或等待请求处理完成的返回令牌;

6.3 Gataway

        SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty,因此Gataway的性能比较高效

        注意:gataway基于webflux,因此与spring web 不兼容

6.3.1 使用Gataway

        创建Gataway子项目,连接父项目

        主启动类开启@EnableEurekaClient

6.3.1.1 配置配置类

server:
  port: 8600
spring:
  application:
    name: gataway   #微服务名字,很重要,微服务可以根据微服务的名字自动形成集群,微服务的名字中不要出现下划线
  cloud:
    gateway:
      routes:
        - id: goods             #路由名(任意)
          uri: lb://GOODS       #要调用的微服务   lb:负载均衡
          predicates:           #匹配的路径
            - Path=/goods/**
        - id: order
          uri: lb://ORDER       #要调用的微服务   lb:负载均衡
          predicates:           #匹配的路径
            - Path=/order/**
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/    #向这个接口注册
  instance:
    instance-id: gataway-8600     #指定当前微服务在注册中心中的id

6.3.1.2 配置过滤器

@Component
@Slf4j
public class AuthFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("gateway过滤器");
        //获取uri
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();
        log.info(path.toString());
        if(requireLogin(path)){
            //需要登录
            List<String> authorization = request.getHeaders().get("authorization");
            if(authorization!=null){
                String token = authorization.get(0);
                log.info(token);
                return chain.filter(exchange);
            }else{
                //没登陆
                ServerHttpResponse response = exchange.getResponse();
                ResponseResult<Boolean> responseResult = new ResponseResult<>(ResponseResult.NO_LOGIN,"请登录",false);
                try {
                    //转换成json字符串
                    String json = new ObjectMapper().writeValueAsString(responseResult);

                    //转byte数组
                    byte[] data = json.getBytes(StandardCharsets.UTF_8);

                    //将数组封装到buffer
                    DataBuffer buffer = response.bufferFactory().wrap(data);

                    //设置响应头
                    response.getHeaders().add("Content-Type","application/json;charset=utf-8");

                    //返回数据,并终止
                    return response.writeWith(Mono.just(buffer));
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
            }
        }
        //放行
        return chain.filter(exchange);
    }
    @Override
    public int getOrder() {
        return 0;
    }
    private boolean requireLogin(String uri){
        //将不需要登录就能操作的uri罗列出来
        String[] uris = {"/user/login","/user/register","/kill/info","/nginx/port"};
        String[] staticResource = {"/goods/info/","/goods/find/","/images/"};
        for (String s : uris) {
            if(uri.equals(s) ){
                return false;
            }
        }
        for (String s : staticResource) {
            if(uri.startsWith(s)){
                return false;
            }
        }
        return true;
    }
}

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

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

相关文章

设置前端项目站标 favicon.ico

1、首先我们需要准备一个小图标利用在线ico工具制作 .ico 的文件 在线工具favicon制作 - 在线工具favicon在线制作,icon制作,网站图标,网站图标制作,ico图标制作https://tool.lu/favicon/选择自己想要制作的小图标&#xff0c;然后选择48*48的下载就可以了 将下载的文件名改为f…

leetcode 123. 买卖股票的最佳时机 III

2023.8.21 本题限制了买卖次数&#xff1a;最多买卖两次。 与之前的股票问题相比&#xff0c;dp数组的第二个维度需要设置四个状态&#xff1a; 第一次持有股票第一次不持有股票第二次持有股票第二次不持有股票 ps&#xff1a;持有股票不等于购买股票&#xff01;&#xff01…

【Git版本控制工具使用---讲解一】

Git版本控制工具使用 安装设置用户名签名和邮箱Git常用的命令 初始化本地库查看本地状态Git 命令添加暂存区提交本地库查看版本信息修改文件版本穿梭 安装 首先根据自身电脑的配置选择性的安装是32位的还是64位的Git版本控制工具 我这边安装的是64位的 以下是我安装的时候的过…

jmeter HTTP信息头管理器

首先&#xff0c;打开JMeter并创建一个新的测试计划。右键单击测试计划&#xff0c;选择"添加" > “线程组”&#xff0c;然后在线程组上右键单击&#xff0c;选择"添加" > “Sampler” > “HTTP请求”。 在HTTP请求中填写服务器的URL和其他必要…

深入浅出带你玩转栈与队列——【数据结构】

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; 目录 1.栈 1.1栈的概念及结构 1.2栈的结构特征图 ​编辑 1.3栈的实现 1.3.1栈的初始化 1.3.2进栈 1.3.3出栈 1.3.4销毁内存 1.3.5判断栈是否为空 1.3.5栈底元素的读取 1.3.6栈中大小 1.4栈实现所有接口 2…

时序预测 | MATLAB实现SO-CNN-BiLSTM蛇群算法优化卷积双向长短期记忆神经网络时间序列预测

时序预测 | MATLAB实现SO-CNN-BiLSTM蛇群算法优化卷积双向长短期记忆神经网络时间序列预测 目录 时序预测 | MATLAB实现SO-CNN-BiLSTM蛇群算法优化卷积双向长短期记忆神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 时序预测 | MATLAB实现SO-CNN-BiL…

增强数字风险防护管理,天际友盟牵头正式发布GDN·全球数字风险阻断网络

随着数字化进程的加快&#xff0c;企业对于数字风险防护管理的需求与日俱增&#xff0c;其数字足迹、数字资产&#xff0c;甚至高管的个人形象都可能成为不法分子的攻击目标。保护关键数字资产与数据免受外部威胁&#xff0c;提升在线业务运营稳健性的价值毋庸置疑。 8月18日&a…

QQ音乐刷时长和音响力工具-无需密码

QQ音乐刷等级是一款安卓端的QQ音乐刷时长和音响力工具&#xff0c;使用时无需密码登录&#xff0c;直接输入qq号码即可&#xff0c;支持微信账号&#xff0c;每提交一次可以刷99分钟的听歌时长&#xff0c;实时到账&#xff0c;刷的听歌时长可以增加听歌排行榜跟音响力(就是QQ音…

辅助笔记-安装Ubantu20.04.1虚拟机

安装Ubantu20.04.1虚拟机 文章目录 安装Ubantu20.04.1虚拟机步骤一&#xff1a;检查BIOS虚拟化支持步骤二&#xff1a;VMware17安装虚拟机步骤1&#xff1a;新建虚拟机步骤2&#xff1a;验证虚拟机能否上网 步骤三&#xff1a;设置Ubantu语言为中文步骤四&#xff1a;软件仓库镜…

江西景德镇陶瓷三维扫描工艺品瓷器数字化3D打印-CASAIM中科广电

江西景德镇陶瓷是中国著名的传统陶瓷产地&#xff0c;其瓷器作为文化遗产具有重要的历史和艺术价值。对于陶瓷工艺品瓷器的三维扫描和数字化&#xff0c;利用三维激光扫描和3D打印相结合的方式助力文物数字化及复原领域是目前主流的发展趋势。 1. 三维激光扫描操作&#xff1a;…

编织梦想:SpringBoot AOP 教程与自定义日志切面完整实战

什么是 AOP AOP 是指通过预编译方式和运行期动态代理的方式&#xff0c;在不修改源代码的情况下对程序进行功能增强的一种技术。AOP 不是面向对象编程&#xff08;OOP&#xff09;的替代品&#xff0c;而是 OOP 的补充和扩展。它是一个新的维度&#xff0c;用来表达横切问题&a…

一文看懂群晖 NAS 安装 Mysql 远程访问连接

文章目录 1. 安装Mysql2. 安装phpMyAdmin3. 修改User 表4. 本地测试连接5. 安装cpolar6. 配置公网访问地址7. 固定连接公网地址 群晖安装MySQL具有高效、安全、可靠、灵活等优势&#xff0c;可以为用户提供一个优秀的数据管理和分析环境。同时具有良好的硬件性能和稳定性&#…

spring boot 3使用 elasticsearch 提供搜索建议

业务场景 用户输入内容&#xff0c;快速返回建议&#xff0c;示例效果如下 技术选型 spring boot 3elasticsearch server 7.17.4spring data elasticsearch 5.0.1elasticsearch-java-api 8.5.3 pom.xml <dependency><groupId>org.springframework.boot</gr…

如何快速搭建一个预约系统?

如何快速搭建一个预约系统 ? 线上预约系统的出现&#xff0c;为解决线下排队拥堵问题提供了便利和解决方案。通过线上预约&#xff0c;人们可以提前预约时间段&#xff0c;避免了到场后需要长时间等待的情况。以下是线上预约解决线下排队拥堵问题的几个场景&#xff1a; 餐厅…

深入完整的带你了解java对象的比较

目录 元素的比较 1.基本类型的比较 2.对象比较的问题 1.运行结果 2.疑问 3.原因 对象的比较 1.覆写基类的equals 2.基于Comparble接口类的比较 3.基于比较器比较 4.三种方式对比 元素的比较 1.基本类型的比较 在Java 中&#xff0c;基本类型的对象可以直接比较大…

52所韩国大学联合退出QS世界大学排名

因今年QS的全新评估指标&#xff0c;令韩国大学在世界大学的排名中大幅下降&#xff0c;因此韩国52所大学联合发表声明&#xff0c;将不再参加QS世界大学排名。下面知识人网小编做详细介绍。 今年6月28日&#xff0c;QS教育集团正式发布了2024年世界大学排名&#xff0c;见“排…

609. 在系统中查找重复文件

609. 在系统中查找重复文件 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a; 原题链接&#xff1a; 609. 在系统中查找重复文件 https://leetcode.cn/problems/find-duplicate-file-in-system/description/ 完成情况&#xff1a; 解题思…

网络编程(三次握手、四次挥手)

一、Wireshark 窗口介绍 二、 wireshark与对应的OSI七层模型 服务器和客户端的代码不能都运行在ubuntu&#xff0c;因为wireshark抓的是流经真实网卡的数据包。 若将服务器客户端都运行在ubuntu&#xff0c;数据直接经过虚拟网卡通信&#xff0c;而不会经过真实网卡。 三、以太…

QT样式表(一)

目录 QSS样式表设置 1、概念 1、通过UI设计器的可视操作修改 2、通过代码修改 3、从样式文件加载 2、样式表语法 选择器的类型 3、设置背景图片 1、添加资源文件 2、使用label控件 显示头像&#xff0c;在样式表文件中进行设置 3、在项目中添加图片资源 QSS样式表设…

动态规划入门之二维数组的动态规划(过河卒)

P1002 [NOIP2002 普及组] 过河卒 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 过河卒&#xff0c;首先科普一下象棋里面的马的跳跃一步的规则吧&#xff08;这题真够坑人的&#xff0c;连个规则都不给出&#xff0c;害得我第一次交就全wa&#xff09;。一张图解释 大家看所…