05_SpringCloud

news2024/11/25 20:44:30

文章目录

  • SpringCloud
    • 服务调用的负载均衡
      • Ribbon负载均衡
    • 面向接口的服务调用
      • OpenFeign 客户端
      • FeignClient日志输出
      • 服务调用的超时设置
    • 配置中心
      • Nacos配置中心
      • Nacos配置中心的使用
      • Nacos配置的持久化

SpringCloud


服务调用的负载均衡

  • 问题引出
        // 服务发现
        List<ServiceInstance> instances = discoveryClient.getInstances("服务名");
        // 选择一个服务提供者
        URI uri = instances.get(0).getUri();
        // 向选择的服务提供者发起请求
        ResponseEntity<String> response = template.getForEntity(uri.toString() + "/nacos/registry/hello?name={1}", String.class, name);

服务是可以有集群的,在发现了一个服务所有的实例之后,在一次服务调用过程中,我们还需要选择其中一个服务实例,发起调用请求,所以发起调用之前还存在着一个选择过程,这就涉及到了选择的策略问题,该按照何种策略选择出集群中的一个实例呢?

Ribbon负载均衡

  • Ribbon是一个客户端负载均衡器,能够给HTTP客户端带来灵活的控制
  • 实现的核心功能:就是一组选择策略,帮助我们在一个服务集群中,选择一个服务实例,并向该实例发起调用请求
  • Irule这个接口类下面是所有的负载均衡选择策略
策略实现类描述
随机策略RandomRule随机选择server
轮训策略RoundRobinRule轮询选择
重试策略RetryRule对选定的负载均衡策略(轮训)之上重试机制,在一个配置时间段内当选择服务不成功,则一直尝试使用该策略选择一个可用的服务;
最低并发策略BestAvailableRule逐个考察服务,如果服务断路器打开,则忽略,再选择其中并发连接最低的服务
可用过滤策略AvailabilityFilteringRule过滤掉因一直失败并被标记为circuit tripped的服务,过滤掉那些高并发链接的服务(active connections超过配置的阈值)
响应时间加权重策略WeightedResponseTimeRule根据server的响应时间分配权重,响应时间越长,权重越低,被选择到的概率也就越低。响应时间越短,权重越高,被选中的概率越高,这个策略很贴切,综合了各种因素,比如:网络,磁盘,io等,都直接影响响应时间
区域权重策略ZoneAvoidanceRule综合判断服务所在区域的性能,和服务的,轮询选择server并且判断一个AWS Zone的运行性能是否可用,剔除不可用的Zone中的所有server(默认策略
  • RestTemplate整合Ribbon
    • 首先,理论上需要在服务消费者(ribbon-consumer)工程中,添加依赖
    <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
    
    • 但是,因为nacos-discovery已经自己整合了ribbon依赖,所以实际上我们并不需要去添加该依赖
    • 接着,需要增加Config配置类,并且需要修改RestTemplate的配置类,添加@LoadBalance注解
    @Configuration
    public class RestTemplateConfig {
    
        @Bean
        // 开启ribbon的负载均衡
        @LoadBalanced
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }
    
    • 然后在使用RestTemplate发起调用的时候,直接使用服务名进行调用即可
    @RestController
    public class ConsumerController {
    
    //    @Autowired
    //    DiscoveryClient discoveryClient;
        @Autowired
        RestTemplate restTemplate;
    
        @GetMapping("/ribbon/consumer")
        public String ribbonDemo() {
    
            // 1. 创建restTemplate对象
            // RestTemplate restTemplate = new RestTemplate();
            // 从容器中去取RestTemplate对象
    
            // 2. 发起请求
            String url = "http://ribbon-provider/ribbon/provider?name={1}";
    
            // 3. 接收响应,打印结果
            String resp = restTemplate.getForObject(url, String.class, "zs");
    
            return resp;
        }
    }
    
    • 服务消费者的配置项
    # 应用的端口号
    server:
    port: 8005
    
    # 服务集群的名字 spring.application.name
    spring:
    application:
      name: ribbon-consumer
    
    # 注册中心的地址
    cloud:
      nacos:
        discovery:
          server-addr: localhost:8848
    
    • 服务提供者同之前的

  • 指定Ribbon负载均衡策略
  1. 方式一:通过配置文件来指定
# 这里的users是我们的服务名称
ribbon-provider:
  ribbon:
    # 这一行配置的就是实现具体负载均衡策略实现类的全类名
    NFLoadBalancerRuleClassName:    com.netflix.loadbalancer.RandomRule
  1. 方式二:通过配置类来指定
    • 定义配置类
    @Configuration
    public class RibbonConfig {
        
        @Bean
        public IRule ribbonRule() {
            // 比如说采用随即策略,它就会对所有的服务集群生效
            return new RandomRule();
        }
    }
    
    • 定义Ribbon客户端配置
    • 我们自己定义的配置类(比如上面的RibbonConfig配置类),不能被@ComponentScan扫描
    @Configuration
    @RibbonClient(name = "ribbon-provider", configuration = RibbonConfig.class)
    public class ProviderClientConfig {
    }
    
  • 自定义Ribbon的负载均衡策略
public class MyRibbonRule extends AbstractLoadBalancerRule {

    // 初始化配置的方法,可以忽略
    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }

    // 选择策略
    @Override
    public Server choose(Object o) {

        // 1. 获取服务实例列表
        /**
         * getReachableServers():获取可达的服务列表
         * getAllServers():获取所有的服务列表
         */
        List<Server> serverList = getLoadBalancer().getReachableServers();

        // 2. 根据自定义策略选择其中的一个服务实例
        Server server = serverList.get(0);
        
        return server;
    }
}


@Configuration
public class RibbonConfig {

    @Bean
    public IRule ribbonRule() {
        // 采用自定义的负载均衡策略
        return new MyRibbonRule();
    }
}

面向接口的服务调用

  • 问题引出
    • 代码同上
    • 我们会发现,因为我们是使用RestTemplate这个Http客户端发起的Http协议的服务调用请求,因此在发起请求的时候,我们得自己构建请求url,请求参数,获取响应体数据等等,导致我们的代码和Restful风格的Http请求紧密耦合。
    • 那么有没有办法,让我们在服务调用的时候与Restful的请求“解耦”,直接以Java代码中接口调用的方式,来完成服务的调用呢?

OpenFeign 客户端

  • 功能:OpenFeign就可以帮助我们实现,让服务调用代码与Restful风格的Http请求解耦的功能。
  • openFeign其实是一个翻译的角色,帮助我们将方法翻译为http请求
  • 主要流程:(以http://feign-provider/feign/provider?name=xxx为例)
    • 以openFeign调用feignDemo这个方法为例
      1. 获取类上面的FeignClient中的注解的值,这个值就是服务的名字
      2. 获取方法上的注解以及注解的值,注解的类型决定了http的请求类型,注解中的值决定了请求的路径
      3. 获取方法中参数的名字,其实就是方法参数中的注解的值
      4. 获取方法的参数值,其实就是url后面跟的参数值
    • 在FeignClient中定义的方法和远程的目标方法名没有必要保持一致
  • OpenFeign的使用
    • 在服务消费者中导入依赖
    <!-- openFeign -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
    • 服务消费者,需要以面向接口的方式调用其他服务,需要用到OpenFeign,所以需要定义Feign客户端
    @FeignClient(name = "feign-provider")
    public interface ProviderClient {
        @GetMapping("/feign/provider")
        public String feignDemo(@RequestParam("name") String name);
    
        @GetMapping("/feign/provider/stu")
        public Student feignDemo2();
    }
    
    • 在启动类上加注解@EnableFeignClients,才能让我们定义的FeignClient生效
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients
    public class FeignConsumerApplication {
        public static void main(String[] args) {
            SpringApplication.run(FeignConsumerApplication.class, args);
        }
    }
    
    • 使用接口类
    @RestController
    public class FeignDemoController {
    
        @Autowired
        ProviderClient providerClient;
    
        @GetMapping("/feign/consumer")
        public String demo() {
    
            // 使用openFeign远程调用,发起Http请求,调用接口
    
            // 1. 导入openFeign包
    
            // 2. 在启动类上添加注解@EnableFeignClients,表示使用openFeign
    
            // 3. 声明一个接口,接口中的方法和目标服务的暴露方法一致
    
            // 4. 调用
            String resp = providerClient.feignDemo("ls");
    
            // http://feign-provider/feign/provider?name={name}
    
            return resp;
        }
    
        @GetMapping("/feign/student")
        public String demo1() {
            Student student = providerClient.feignDemo2();
            System.out.println("student = " + student);
            return "ok";
        }
    }
    

FeignClient日志输出

  • 当我们调用FeignClient发出请求的时候,如果我们希望能看到其发出的具体Http请求,我们可以通过配置来实现。
    1. 在配置文件中实现
    # 这里的xxx表示我们自己的定义的FeignClient所在包的包名(比如: 		
    # com.coo1heisenberg.feign.consumer.client)
    logging:
    	level:
    		xxx: debug
    
    1. 在配置类中,配置FeignConfig,指定日志输出级别
    @Configuration
    public class FeignConfig {
    
    	@Bean
    	public Logger.Level logLevel() {
        	return Logger.Level.FULL;
    	}
    }
    

服务调用的超时设置

  • 通常,一次远程调用过程中,服务消费者不可能无限制的等待服务提供者返回的结果,正常情况下,服务提供者的一次调用执行过程也不会执行很长时间(除非出现网络故障,或者服务提供者宕机等问题),所以为防止,在非正常情况下服务消费者在调用过程中的长时间阻塞等待,对于一次服务调用过程,我们会设置其超时时间。一次服务调用,超时未返回即认为调用失败。在使用Feign的时候,我们可以配置其超时时间。
# 设置openFeign的超时时间
ribbon:
  #指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
  ReadTimeout: 5000
  #指的是建立连接后从服务器读取到可用资源所用的时间
  ConnectTimeout: 5000

配置中心

类似于注册中心,配置中心的实现也有多种,而Nacos同时也实现了配置中心的角色。

  • 在启动的时候拉取配置,当配置中心中的配置发生变化的时候,服务可以实时的感知到配置的变化
  • 使用配置中心可以以中心化外部化动态化(动态化即可以实时刷新配置)的方式管理所有环境的应用配置和服务配置。
  • 动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。

Nacos配置中心

  • 注册中心的配置信息基本认识
    • 配置中心中的配置,主要是以键值对的形式存在的,即每条配置都以key-value的形式存储,key是配置的名称,value才是配置的值
    • 所以,很明显,不同配置的key值应该有所区别,或者即使key值相同,我们也应该有办法区分他们,即给key值划分不同的维度
  • Nacos的基本概念
    • 配置项: 一个具体的可配置的参数与其值域,通常以 param-key=param-value 的形式存在。例如我们常配置系统的日志输出级别(logLevel=INFO|WARN|ERROR) 就是一个配置项。
    • 配置集:一组相关或者不相关的配置项的集合称为配置集。在系统中,一个配置文件通常就是一个配置集,包含了系统各个方面的配置,每一个配置集都对应一个唯一的DataId,DataId必须由我们自己定义。
    • 配置分组: Nacos 中的一组配置集,是组织配置的维度之一,每一个分组都有一个唯一的组名,如果我们未定义,则默认使用DEFAULT-GROUP分组
    • 命名空间: 用于进行用户粒度的配置隔离,每一个命名空间都有一个唯一的Id值,如果我们未定义,则默认使用public命名空间
      在这里插入图片描述
      • 配置项中的key值,以及配置分组的组名都由我们自己根据场景去定义

      • 命名空间的Id值,在我们定义命名空间的时候,由Nacos帮我们生成

    • 在一个服务启动的时候,默认读取的配置集id即data_id和该服务的配置有关,按照如下公式计算:
    	${prefix}-${spring.profiles.active}.${file-extension}
    
    • prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。

    • spring.profiles.active 即为当前环境对应的 profile,注意:当 spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}

    • file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 propertiesyaml 类型。

    • 这里要主要,我们的SpringBoot项目在启动的时候,就会根据${prefix}-${spring.profiles.active}.${file-extension}生成配置集名称,并自动去读取该配置集名称对应的配置。


Nacos配置中心的使用

  1. nacos-config子工程中添加如下依赖
<dependencies>

    <!-- springboot -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- nacos 配置中心的依赖 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        <version>2.2.0.RELEASE</version>
    </dependency>
</dependencies>
  1. 在nacos-config的目录下添加两个配置文件,分别是bootstrap.ymlapplication.yml,在bootstrap配置文件中必须有应用名,以及nacos服务器地址等,而在application.yml配置文件中,配置自己项目中的其他配置
    在这里插入图片描述
# bootstrap.yml文件

# nacos相关的配置都放到bootstrap.yml中

# nacos配置中心的配置
spring:
  cloud:
    nacos:
      config:
        # 配置中心的地址
        server-addr: localhost:8848
        # 配置中心中配置集的类型
        file-extension: yaml
        # 默认是 DEFAULT_GROUP
        group: test_group
        # 默认是public,配置命名空间的id
        namespace: d6dabccd-c9fa-47d3-93a8-526885ab302a
        # 共享的配置
        shared-configs: 
          - data-id: common.yaml
            group: test_group
            refresh: true  # 共享配置也支持动态刷新


  # ${prefix}-${spring.profiles.active}.${file-extension}
  # nacos-config
  application:
    name: nacos-config-test

  # 多环境配置 (dev / test / prod)
  profiles:
    active: prod
  # {spring.application.name}-{spring.profiles.active}.{file-extension}
  # dataId:nacos-config-dev.yaml
# application.yml文件

server:
  port: 8080
  1. 在nacos中添加配置集
    在这里插入图片描述
  2. 测试代码
@RefreshScope // 实现配置的动态刷新
@RestController
public class testController {

    @Value("${coo1heisenberg.name}")
    String name;

    @GetMapping("/test")
    public String test() {
        return name + " hello nacos";
    }
}

Nacos配置的持久化

  • 在Nacos服务器上写入的配置,会被持久化保存到Nacos自带的一个嵌入式数据库derby中,因此当我们重启Nacos之后,仍然可以看到之前的配置信息
  • 使用嵌入式数据库实现数据的存储,不方便观察数据存储的基本情况,因此,Nacos还支持将配置信息写入Mysql中
    • 在数据库中,创建名为nacos的数据库
    • 在nacos数据库中,执行数据库初始化文件:nacos-mysql.sql(改文件在conf目录下已经提供)
    • 修改conf/application.properties文件,增加支持mysql数据源配置(目前只支持mysql),添加mysql数据源的url、用户名和密码。
    spring.datasource.platform=mysql
    db.num=1
    # 这里的url要改成你自己的mysql数据库地址,并在你的mysql中创建名为nacos的数据库
    db.url.0=jdbc:mysql://11.162.196.16:3306/nacos?	characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
    # 这里要改成你自己登录mysql的用户名和密码
    db.user.0=nacos_devtest
    db.password.0=youdontknow
    
    在这里插入图片描述
  • 在配置了mysql数据库之后,我们会发现,之前配置中心的配置信息全部消失了,那是因为我们之前使用的是nacos的内嵌数据库derby,现在切换到mysql之后数据存储在nacos这个数据库中,而该数据库现在是没有数据的。
    在这里插入图片描述

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

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

相关文章

第十二届蓝桥杯省赛真题 Java C 组【原卷】

文章目录 发现宝藏【考生须知】试题 A: ASC试题 B: 空间试题 C: 卡片试题 D: 相乘试题 E: 路径试题 F: 时间显示试题 G: 最少砝码试题 H : \mathrm{H}: H: 杨辉三角形试题 I: 左孩子右兄弟试题 J : \mathrm{J}: J: 双向排序 发现宝藏 前些天发现了一个巨牛的人工智能学习网站…

【SpringBoot篇】基于Redis分布式锁的 误删问题 和 原子性问题

文章目录 &#x1f354;Redis的分布式锁&#x1f6f8;误删问题&#x1f388;解决方法&#x1f50e;代码实现 &#x1f6f8;原子性问题&#x1f339;Lua脚本 ⭐利用Java代码调用Lua脚本改造分布式锁&#x1f50e;代码实现 &#x1f354;Redis的分布式锁 Redis的分布式锁是通过利…

傻傻分不清楚:JDK/JRE/JVM的区别和联系

在Java开发的世界里&#xff0c;JDK、JRE和JVM是三个经常听到的术语。 对于初学者来说&#xff0c;它们的概念和区别可能会让人感到困惑。 这篇文章详细解释下三个组件的含义、它们之间的区别和联系。 一&#xff0c;JDK&#xff1a;Java Development Kit JDK是Java开发工具…

umi6.x + react + antd的项目增加403(无权限页面拦截),404,错误处理页面

首先在src/pages下创建403&#xff0c;404&#xff0c;ErrorBoundary 403 import { Button, Result } from antd; import { history } from umijs/max;const UnAccessible () > (<Resultstatus"403"title"403"subTitle"抱歉&#xff0c;您无权…

shell-for循环语句练习题

1.计算从1到100所有整数的和 [rootlocalhost ~]# vim 1.sh #!/bin/bash sum0 #定义变量sum初始值为0 for i in {1..100} #for循环 i取值从1到100 do sum$[ isum ] #在每次循环中&#xff0c;变量i的值会依次取1到100的整数值。 #sum是一个累加器&#xff0c;初始值…

2024数维杯C题24页完整解题思路+1-4问代码解题+运行高清结果图

C题天然水合物资源量评价 点击链接加入群聊【2024数维杯数学建模ABC题资料汇总】&#xff1a; 2024数维杯C题完整思路24页配套代码1-4问后续参考论文https://www.jdmm.cc/file/2710638 下面内容是持续更新的 根据勘探数据确定天然气水合物资源的分布范围。 假设勘探区域内的…

Python深度学习基于Tensorflow(4)Tensorflow 数据处理和数据可视化

文章目录 构建Tensorflow.data数据集TFRecord数据底层生成TFRecord文件数据读取TFRecord文件数据图像增强 数据可视化 构建Tensorflow.data数据集 tf.data.Dataset表示一串元素&#xff08;element&#xff09;&#xff0c;其中每个元素包含一个或多个Tensor对象。例如&#xf…

【SVN-TortoiseSVN】SVN 的简介与TortoiseSVN 安装使用教程

目录 &#x1f31e;前言 &#x1f30a;1. SVN 的简介 &#x1f30d;1.1 SVN是什么 &#x1f30d;1.2 SVN 工作原理 &#x1f30d;1.3 TortoiseSVN 术语及定义 &#x1f30a;2. TortoiseSVN 安装与汉化 &#x1f30a;3. SVN 基本操作-TortoiseSVN &#x1f30d;3.1 浏览…

35个矩阵账号,如何通过小魔推打造2704万+视频曝光?

在如今的短视频时代&#xff0c;矩阵发布的作用被发挥到极致&#xff0c;通过各个短视频平台的流量分发&#xff0c;虽然视频质量不如那些头部的IP&#xff0c;但是在视频数量上却能做到轻松碾压&#xff0c;让自己的品牌与门店有更多的声量&#xff0c;这就是如今短视频平台对…

sbt安装

一、sbt介绍 在Spark中&#xff0c;sbt&#xff08;Scala Build Tool&#xff09;是一个用于构建Scala项目的工具。它是Spark项目的主要构建工具之一&#xff0c;用于编译Scala代码、管理依赖项、打包应用程序以及执行其他与项目构建相关的任务。 sbt的用途在Spark开发中主要…

云管平台-助力企业云管理飞跃发展!

随著信息技术的快速发展&#xff0c;以及企业数字化的快速改革&#xff0c;云计算已经成为企业信息化建设的重要基石。随着企业云计算的快速应用&#xff0c;以及业务的快速发展&#xff0c;如何快速管理各种云&#xff0c;降低云成本等迫在眉睫。在这个背景下&#xff0c;云管…

使用flutter开发一个U盘文件管理APP,只解析图片文件

今天教大家用flutter撸一个U盘文件管理APP,需求是这样的: 当我在Android设备上插入U盘后,我能在APP中打开U盘的文件目录,并且能进入对应目录的下一级目录,如果下级目录下有图片文件,我就对这个图片文件进行解析,并展示出来。 需求了解后,先上个效果图: 效果图看完后,…

springboot如何查看版本号之间的相互依赖

第一种&#xff1a; 查看本地项目maven的依赖&#xff1a; ctrl鼠标左键&#xff1a;按下去可以进入maven的下一层&#xff1a; ctrl鼠标左键&#xff1a;按下去可以进入maven的再下一层&#xff1a; 就可以查看springboot的一些依赖版本号了&#xff1b; 第二种&#xff1a; 还…

# 从浅入深 学习 SpringCloud 微服务架构(十五)

从浅入深 学习 SpringCloud 微服务架构&#xff08;十五&#xff09; 一、SpringCloudStream 的概述 在实际的企业开发中&#xff0c;消息中间件是至关重要的组件之一。消息中间件主要解决应用解耦&#xff0c;异步消息&#xff0c;流量削锋等问题&#xff0c;实现高性能&…

经开区创维汽车车辆交接仪式顺利举行,守护绿色出行助力低碳发展

5月10日&#xff0c;“创维新能源汽车进机关”交车仪式于徐州顺利举行&#xff0c;20辆创维EV6 II正式交付经开区政府投入使用。经开区陈琳副书记、党政办公室副主任张驰主任、经开区公车管理平台苑忠民科长、创维汽车总裁、联合创始人吴龙八先生、创维汽车营销公司总经理饶总先…

【计算机毕业设计】基于SSM++jsp的蜀都天香酒楼网站【源码+lw+部署文档+讲解】

目录 摘要 Abstract 目 录 1绪论 1.1研究背景与意义 1.2国内外研究现状 1.3研究内容 1.4论文结构 2相关技术介绍 2.1 B/S模式 2.2 MyEclipse开发环境 2.3 MySQL数据库 2.4 Java语言 2.5 JSP技术 2.6 Tomcat服务器 3系统分析 3.1需求分析 3.2可行性分析 3.2.1经济可行性 3.2.2技…

【MySQL探索之旅】JDBC (Java连接MySQL数据库)

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更…

机器学习算法 - 逻辑回归

逻辑回归是一种广泛应用于统计学和机器学习领域的回归分析方法&#xff0c;主要用于处理二分类问题。它的目的是找到一个最佳拟合模型来预测一个事件的发生概率。以下是逻辑回归的一些核心要点&#xff1a; 基本概念 输出&#xff1a;逻辑回归模型的输出是一个介于0和1之间的…

容器化Jenkins远程发布java应用(方式二:自定义镜像仓库远程拉取构建)

1.创建maven项目 2.配置git、maven 3.阿里控制台>容器镜像服务>镜像仓库>创建镜像仓库 4.执行shell脚本&#xff08;推送镜像到阿里云镜像仓库&#xff09; 使用到登录阿里云仓库命令 #!/bin/bash # 服务名称 SERVER_NAMEplanetflix-app # 镜像tag IMAGE_TAG1.0.0-SN…

每日两题 / 24. 两两交换链表中的节点 25. K 个一组翻转链表(LeetCode热题100)

24. 两两交换链表中的节点 - 力扣&#xff08;LeetCode&#xff09; 定义三个指针&#xff0c;交换前先保存ntnt指针为next->next&#xff0c;cur和next两个节点&#xff0c;然后将pre->next指向next 若pre为空&#xff0c;说明当前交换的节点为头两个节点&#xff0c;…