当前位置: 首页 > 编程日记 > 正文

一键部署 SpringCloud 微服务,这套流程值得学习一波儿!

前言

一键部署 springcloud 微服务,需要用到 Jenkins K8S Docker等工具。

本文使用jenkins部署,流程如下图

图片

  1. 开发者将代码push到git
  2. 运维人员通过jenkins部署,自动到git上pull代码
  3. 通过maven构建代码
  4. 将maven构建后的jar打包成docker镜像 并 push docker镜像到docker registry
  5. 通过k8s发起 发布/更新 服务 操作

其中 2~5步骤都会在jenkins中进行操作

1、开发者将代码PUSH到Git

这一步本文不做详细描述

2、通过Jenkins部署,自动到Git上PULL代码

这里需要用到Jenkins 的 pipeline插件

2.1、 配置SSH-KEY

因为jenkins需要pull git上的代码,正常来说,代码都是私有的,git clone操作的时候会需要密码,就不能完成自动化操作了。这里使用SSH-KEY 的方式,让git clone操作无需密码就能完成克隆

2.1.1、生成/添加SSH公钥

在jenkins所在环境里执行

ssh-keygen -t ed25519 -C "xxxxx@xxxxx.com"  

注意:这里的 xxxxx@xxxxx.com 只是生成的 sshkey 的名称,并不约束或要求具体命名为某个邮箱,现网的大部分教程均讲解的使用邮箱生成,其一开始的初衷仅仅是为了便于辨识所以使用了邮箱

按照提示完成三次回车,即可生成 ssh key。通过查看 ~/.ssh/id_ed25519.pub 文件内容,获取到你的 public key

图片

得到公钥 public key 内容

cat ~/.ssh/id_ed25519.pub

复制备用

2.1.2、将公钥配置到git平台

git平台可以是github,gitee,也可以是自己搭建的gitlab等

我这里使用gitee

通过仓库主页 「管理」->「部署公钥管理」->「添加部署公钥」 ,添加生成的 public key 添加到仓库中。

图片

添加成功后,到jenkins所在环境运行

ssh -T git@gitee.com

图片

首次使用需要确认并添加主机到本机SSH可信列表。若返回 Hi XXX! You’ve successfully authenticated, but Gitee.com does not provide shell access. 内容,则证明添加成功

2.1.3、测试

复制你项目的SSH链接

图片

在jenkins所在环境

执行git clone git@gitee.com:xxxx.git

图片

2.2、配置Jenkins的pipeline 自动clone代码
2.2.1、Jenkins创建任务

新建任务

图片

选择流水线 确定

图片

这里勾选参数化构建,选择字符参数,用于输入构建代码的版本

图片

默认值填master,根据自身项目实际填写

图片

拉到最下面的流水线,写pipeline脚本,如果不知道怎么写,可以点击流水线语法进行参考

图片

这是我的脚本, REPOSITORY 填写项目的ssh地址,REPOSITORY_VERSION是刚刚配置的构建参数

pipeline {
    agent any
    
    environment {
        REPOSITORY="git@gitee.com:xxxxxx/cloud-demo.git"
    }
    
    stages {
        stage('拉代码') {
            steps {
                echo "start fetch code from git:${REPOSITORY}"
                deleteDir()
                git branch: "${REPOSITORY_VERSION}", url: "${REPOSITORY}"
            }
        }
    }
}

保存

2.2.2、测试拉代码流程*

返回Jenkins 首页,选择刚刚创建的项目

图片

点击右边的运行按钮

图片

输入代码分支版本

点击开始构建

图片

看到这里就是已经构建成功了

图片

根据日志提示的目录,可以看到目录下已经有代码了

3、通过maven构建代码

3.1、maven插件安装

因为这里使用到了maven,jenkins需要先安装maven工具

3.2、maven构建项目

补充pipeline脚本

pipeline {
    agent any
    
    environment {
        REPOSITORY="git@gitee.com:xxxxxx/cloud-demo.git"
        MODULE="cloud-demo-m-test-dubbo-service"
    }
    
    stages {
        stage('拉代码') {
            steps {
                echo "start fetch code from git:${REPOSITORY}"
                deleteDir()
                git branch: "${REPOSITORY_VERSION}", url: "${REPOSITORY}"
            }
        }
        
        stage('编译代码') {
            steps {
                echo "start compile"
                sh "cd cloud-demo-project && mvn -U clean install"
                echo "compile project ................................"
                sh "cd cloud-demo-dependencies && mvn -U clean install"
                echo "compile dependencies ................................"
                sh "cd cloud-demo-common && mvn -U clean install"
                echo "compile common ................................"
                sh "cd cloud-demo-m-test && mvn -U -am clean install"
                echo "compile m-test ................................"
                sh "cd cloud-demo-m-test/cloud-demo-m-test-common && mvn -U -am clean install"
                echo "compile m-test-dubbo-api ................................"
                sh "cd cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-api && mvn -U -am clean install"
                echo "compile m-test-dubbo-service ................................"
                sh "cd cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service && mvn -U -am clean package"
            }
        }
    }
}

这里补充了stage('编译代码') {} 部分,用于maven编译。具体编译脚本需要根据自己项目实际,这个是我项目的编译必须步骤。

3.3、测试拉代码流程+构建项目过程

重复2.2.2步骤,查看运行结果

图片

构建成功

4、将maven构建后的jar打包成docker镜像 并 push docker镜像到docker registry

在jenkins环境下,创建目录用于存放脚本文件

mkdir /usr/local/project/.env/cloud-demo-m-test-dubbo-service/ -p

这个目录下存放4个文件

  • build.sh
  • Dockerfile
  • application.properties
  • bootstrap.properties

application.propertiesbootstrap.properties 是springcloud的配置文件,内容根据自己项目情况

buils.sh 文件内容

#!/usr/bin/env bash

REPOSITORY_VERSION=$1
GIT_REVISION=`git log -1 --pretty=format:"%h"`
TIME=`date "+%Y.%m.%d.%H.%M"`
IMAGE_NAME=192.168.31.100:5000/cloud-demo/cloud-demo-m-test-dubbo-service
IMAGE_TAG=${REPOSITORY_VERSION}-${GIT_REVISION}-${TIME}

docker build -t ${IMAGE_NAME}:${IMAGE_TAG} .

docker push ${IMAGE_NAME}:${IMAGE_TAG}

echo "${IMAGE_NAME}:${IMAGE_TAG}" > IMAGE
## 内容说明
REPOSITORY_VERSION 是需要传入的参数,传项目git分支名,用于打标签使用
GIT_REVISION 是获取当前git的提交版本 如 c9c8525,线上问题可以根据这个版本查找具体代码问题
TIME 年.月.日.时.分  记录打包时间,也用于打标签使用
IMAGE_NAME 镜像名,这里前缀包含了192.168.31.100:5000 是因为我打包之后会push到192.168.31.100:5000,其他服务器可以到这里来pull镜像
docker build -t ${IMAGE_NAME}:${IMAGE_TAG} . 构建镜像
docker push ${IMAGE_NAME}:${IMAGE_TAG}  推送镜像
echo "${IMAGE_NAME}:${IMAGE_TAG}" > IMAGE  把镜像名:镜像标签 输出到IMAGE文件里,方便后续步骤获取

Dockerfile 文件内容

FROM openjdk:8u342-jdk
MAINTAINER yanger yanger@qq.com

COPY target/cloud-demo-m-test-dubbo-service-1.0-SNAPSHOT.jar /cloud-demo-m-test-dubbo-service.jar
COPY application.properties /application.properties
COPY bootstrap.properties /bootstrap.properties
ENTRYPOINT ["java", "-jar", "/cloud-demo-m-test-dubbo-service.jar"]
## 内容说明
FROM openjdk:8u342-jdk 使用openjdk:8u342-jdk 作为基础镜像
COPY 文件到镜像
ENTRYPOINT ["java", "-jar", "/cloud-demo-m-test-dubbo-service.jar"] 启动时运行 java -jar /cloud-demo-m-test-dubbo-service.jar

这里用到了docker registry 如果还没有registry 请先启动,可以用docker的方式启动

docker run -d -p 5000:5000 --name registry registry

build.sh文件需要可执行权限

chmod 755 build.sh

补充pipeline脚本

pipeline {
    agent any
    
    environment {
        REPOSITORY="git@gitee.com:xxxxxx/cloud-demo.git"
        SCRIPT_PATH="/usr/local/project/.env/cloud-demo-m-test-dubbo-service/"
    }
    
    stages {
        stage('拉代码') {
            steps {
                echo "start fetch code from git:${REPOSITORY}"
                deleteDir()
                git branch: "${REPOSITORY_VERSION}", url: "${REPOSITORY}"
            }
        }
        
        stage('编译代码') {
            steps {
                echo "start compile"
                sh "cd cloud-demo-project && /usr/local/maven/bin/mvn -U clean install"
                echo "compile project ................................"
                sh "cd cloud-demo-dependencies && /usr/local/maven/bin/mvn -U clean install"
                echo "compile dependencies ................................"
                sh "cd cloud-demo-common && /usr/local/maven/bin/mvn -U clean install"
                echo "compile common ................................"
                sh "cd cloud-demo-m-test && /usr/local/maven/bin/mvn -U -am clean install"
                echo "compile m-test ................................"
                sh "cd cloud-demo-m-test/cloud-demo-m-test-common && /usr/local/maven/bin/mvn -U -am clean install"
                echo "compile m-test-dubbo-api ................................"
                sh "cd cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-api && /usr/local/maven/bin/mvn -U -am clean install"
                echo "compile m-test-dubbo-service ................................"
                sh "cd cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service && /usr/local/maven/bin/mvn -U -am clean package"
            }
        }

        stage('构建镜像') {
            steps {
                echo "start build image"
                sh "cp ${SCRIPT_PATH}/build.sh cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "cp ${SCRIPT_PATH}/Dockerfile cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "cp ${SCRIPT_PATH}/application.properties cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "cp ${SCRIPT_PATH}/bootstrap.properties cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "cd cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/ && ./build.sh ${REPOSITORY_VERSION}"
            }
        }

    }
}

补充了stage(‘构建镜像’){} 内容和environment 部分加了个参数 SCRIPT_PATH

SCRIPT_PATH参数是上面创建的文件夹路径

stage(‘构建镜像’){}这一步是复制相应文件到项目目录下,并且执行build.sh脚本

测试

图片

可以看到镜像已经打包好,并且已经push到registry了

  • 浏览器访问http://192.168.31.100:5000/v2/cloud-demo/cloud-demo-m-test-dubbo-service/tags/list可以看到registry有cloud-demo/cloud-demo-m-test-dubbo-service:master-7012e1d-2023.05.01.10.16这个镜像

5、通过k8s发起 发布/更新 服务 操作

5.1、配置构建K8S资源的描述文件
  • /usr/local/project/.env/cloud-demo-m-test-dubbo-service/ 目录新增文件 cloud-demo-m-test-dubbo-service.yaml

文件内容

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: cloud-demo-m-test-dubbo-service
  name: cloud-demo-m-test-dubbo-service
spec:
  replicas: 1
  selector:
    matchLabels:
      app: cloud-demo-m-test-dubbo-service
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: cloud-demo-m-test-dubbo-service
    spec:
      containers:
      - image: IMAGE_AND_TAG
        name: cloud-demo-m-test-dubbo-service
        resources: {}
        volumeMounts: 
        - name: log-path
          mountPath: /logs
      volumes: 
      - name: log-path
        hostPath: 
          path: /root/k8s/cloud-demo-m-test-dubbo-service/logs
status: {}

---

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: cloud-demo-m-test-dubbo-service
  name: cloud-demo-m-test-dubbo-service
spec:
  ports:
  - port: 20881
    protocol: TCP
    targetPort: 20881
  selector:
    app: cloud-demo-m-test-dubbo-service
  type: NodePort
status:
  loadBalancer: {}

这个文件是构建K8S资源的描述文件,创建deploymentservice,暴露端口20881,挂载/logs目录到主机

其中 IMAGE_AND_TAG 是需要替换为相应 容器名:容器标签

5.2、完善jenkins步骤
pipeline {
    agent any
    
    environment {
        REPOSITORY="git@gitee.com:xxxxxx/cloud-demo.git"
        SCRIPT_PATH="/usr/local/project/.env/cloud-demo-m-test-dubbo-service"
        IMAGE=""
    }
    
    stages {
        stage('拉代码') {
            steps {
                echo "start fetch code from git:${REPOSITORY}"
                deleteDir()
                git branch: "${REPOSITORY_VERSION}", url: "${REPOSITORY}"
            }
        }
        
        stage('编译代码') {
            steps {
                echo "start compile"
                sh "cd cloud-demo-project && /usr/local/maven/bin/mvn -U clean install"
                echo "compile project ................................"
                sh "cd cloud-demo-dependencies && /usr/local/maven/bin/mvn -U clean install"
                echo "compile dependencies ................................"
                sh "cd cloud-demo-common && /usr/local/maven/bin/mvn -U clean install"
                echo "compile common ................................"
                sh "cd cloud-demo-m-test && /usr/local/maven/bin/mvn -U -am clean install"
                echo "compile m-test ................................"
                sh "cd cloud-demo-m-test/cloud-demo-m-test-common && /usr/local/maven/bin/mvn -U -am clean install"
                echo "compile m-test-dubbo-api ................................"
                sh "cd cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-api && /usr/local/maven/bin/mvn -U -am clean install"
                echo "compile m-test-dubbo-service ................................"
                sh "cd cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service && /usr/local/maven/bin/mvn -U -am clean package"
            }
        }

        stage('构建镜像') {
            steps {
                echo "start build image"
                sh "cp ${SCRIPT_PATH}/build.sh cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "cp ${SCRIPT_PATH}/Dockerfile cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "cp ${SCRIPT_PATH}/application.properties cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "cp ${SCRIPT_PATH}/bootstrap.properties cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "cd cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/ && ./build.sh ${REPOSITORY_VERSION}"
            }
        }

        stage('发布') {
            steps {
                echo "start deploy"
                script {
                    IMAGE = readFile "cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/IMAGE"
                    IMAGE = IMAGE.trim()
                    if (IMAGE == "") {
                        throw new Exception("获取镜像名文件失败,请重试")
                    }
                }
                echo "IMAGE: -- ${IMAGE}"
                sh "cp ${SCRIPT_PATH}/cloud-demo-m-test-dubbo-service.yaml cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "sed -i \"s#IMAGE_AND_TAG#${IMAGE}#g\" cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/cloud-demo-m-test-dubbo-service.yaml"
                sh "kubectl apply -f cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/cloud-demo-m-test-dubbo-service.yaml"
            }
        }
    }
}

添加了 stage('发布') {} 部分

  • 通过读取IMAGE文件,获取镜像名:镜像标签
  • 如果获取不到镜像名:镜像标签,抛出异常
  • cloud-demo-m-test-dubbo-service.yaml文件复制到工作目录
  • 用镜像名:镜像标签 替换掉 IMAGE_AND_TAG
  • 使用kubectl命令发布/更新服务
5.3、测试

在jenkins上构建项目

图片

在K8S master服务器上,执行

kubectl get all

图片

搞定!

相关文章:

Yolov11-detect训练自己的数据集

至此,整个YOLOv11的训练预测阶段完成,与YOLOv8差不多。欢迎各位批评指正。

SpringCloud Alibaba集成 Gateway(自定义负载均衡器)、Nacos(配置中心、注册中心)、Loadbalancer

要为未被某些网关路由谓词处理的请求提供相同的CORS配置,请将属性spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping设置为true。断言(Predicate):Java8中的断言函数,Spring Cloud Gateway中的断言函数输入类型是 Spring5.0框架中的ServerWebExchange。对于所有GET请求的路径,来自docs.spring.io的请求都将允许CORS请求。

HackQuest介绍 web3 学习平台

官网地址: https://www.hackquest.io/zhHackQuest是一个专注于Web3技术教育的在线学习平台,旨在帮助全球开发者掌握区块链、加密货币和去中心化应用(DApps)领域的最新技能。该平台汇聚了超过14000名活跃开发者,与100多个领先的Web3生态系统和项目紧密合作,为用户提供全面的教育资源。

YOLOv10训练自己的数据集

至此,整个YOLOv10的训练预测阶段完成,与YOLOv8差不多。欢迎各位批评指正。

YOLOv10环境搭建、模型预测和ONNX推理

运行后会在文件yolov10s.pt存放路径下生成一个的yolov10s.onnxONNX模型文件。安装完成之后,我们简单执行下推理命令测试下效果,默认读取。终端,进入base环境,创建新环境。(1)onnx模型转换。

常见的七种加密算法及实现

**数字签名**、**信息加密** 是前后端开发都经常需要使用到的技术,应用场景包括了用户登入、交易、信息通讯、`oauth` 等等,不同的应用场景也会需要使用到不同的签名加密算法,或者需要搭配不一样的 **签名加密算法** 来达到业务目标。这里简单的给大家介绍几种常见的签名加密算法和一些典型场景下的应用。## 正文### 1. 数字签名**数字签名**,简单来说就是通过提供 **可鉴别** 的 **数字信息** 验证 **自身身份** 的一种方式。一套 **数字签名** 通常定义两种 **互补

7min到40s:SpringBoot 启动优化实践

然后重点排查这些阶段的代码。先看下。

SpringBoot系列教程之Bean之指定初始化顺序的若干姿势

之前介绍了@Order注解的常见错误理解,它并不能指定 bean 的加载顺序,那么问题来了,如果我需要指定 bean 的加载顺序,那应该怎么办呢?本文将介绍几种可行的方式来控制 bean 之间的加载顺序。

在Java中使用WebSocket

WebSocket是一种协议,用于在Web应用程序和服务器之间建立实时、双向的通信连接。它通过一个单一的TCP连接提供了持久化连接,这使得Web应用程序可以更加实时地传递数据。WebSocket协议最初由W3C开发,并于2011年成为标准。

3种方案,模拟两个线程抢票

在多线程编程中,资源竞争是一个常见的问题。资源竞争发生在多个线程试图同时访问或修改共享资源时,可能导致数据不一致或其他并发问题。在模拟两个线程抢票的场景中,我们需要考虑如何公平地分配票,并确保每个线程都有机会成功获取票。本篇文章将通过三种方式来模拟两个线程抢票的过程,以展示不同的并发控制策略。使用 Synchronized 来确保一次只有一个线程可以访问票资源。使用 ReentrantLock 来实现线程间的协调。使用 Semaphore 来限制同时访问票的线程数量。

替代Druid,HakariCP 为什么这么快?

这次源码探究,真的感觉看到了无数个小细节,无数个小优化,积少成多。平时开发过程中,一些小的细节也一定要“扣”。

Java中volatile 的使用场景有哪些?

volatile是一种轻量级的同步机制,它能保证共享变量的可见性,同时禁止重排序保证了操作的有序性,但是它无法保证原子性。所以使用volatilevolatile。

JDK22 正式发布了 !

Java 22 除了推出了新的增强功能和特性,也获得 Java Management Service (JMS) 的支持,这是一项新的 Oracle 云基础设施远程软件服务(Oracle Cloud Infrastructure, OCI) 原生服务,提供统一的控制台和仪表盘,帮助企业管理本地或云端的 Java 运行时和应用。使包含运行时计算值的字符串更容易表达,简化 Java 程序的开发工作,同时提高将用户提供的值编写成字符串,并将字符串传递给其他系统的程序的安全性。支持开发人员自由地表达构造器的行为。

Jackson 用起来!

你可以创建自定义序列化器和反序列化器以自定义特定字段或类的序列化和反序列化行为。为此,请创建一个实现或接口的类,并在需要自定义的字段或类上使用和注解。@Override// ...其他代码...优势性能优异:Jackson在序列化和反序列化过程中表现出优秀的性能,通常比其他Java JSON库更快。灵活性:通过注解、自定义序列化器/反序列化器等功能,Jackson提供了丰富的配置选项,允许你根据需求灵活地处理JSON数据。易于使用:Jackson的API设计简洁明了,易于学习和使用。

拜托!别再滥用 ! = null 判空了!!

另外,也许受此习惯影响,他们总潜意识地认为,所有的返回都是不可信任的,为了保护自己程序,就加了大量的判空。如果你养成习惯,都是这样写代码(返回空collections而不返回null),你调用自己写的方法时,就能大胆地忽略判空)这种情况下,null是个”看上去“合理的值,例如,我查询数据库,某个查询条件下,就是没有对应值,此时null算是表达了“空”的概念。最终,项目中会存在大量判空代码,多么丑陋繁冗!,而不要返回null,这样调用侧就能大胆地处理这个返回,例如调用侧拿到返回后,可以直接。

详解Java Math类的toDegrees()方法:将参数从弧度转换为角度

Java Math 类的 toDegrees() 方法是将一个角度的弧度表示转换为其度表示,返回值为double类型,表示从弧度数转换而来的角度数。这就是Java Math 类的 toDegrees() 方法的攻略。我们已经了解了该方法的基本概念、语法、注意事项以及两个示例。希望这篇攻略对你有所帮助。

SpringBoot接口防抖(防重复提交)的一些实现方案

作为一名老码农,在开发后端Java业务系统,包括各种管理后台和小程序等。在这些项目中,我设计过单/多租户体系系统,对接过许多开放平台,也搞过消息中心这类较为复杂的应用,但幸运的是,我至今还没有遇到过线上系统由于代码崩溃导致资损的情况。这其中的原因有三点:一是业务系统本身并不复杂;二是我一直遵循某大厂代码规约,在开发过程中尽可能按规约编写代码;三是经过多年的开发经验积累,我成为了一名熟练工,掌握了一些实用的技巧。啥是防抖所谓防抖,一是防用户手抖,二是防网络抖动。

公司新来一个同事:为什么 HashMap 不能一边遍历一边删除?一下子把我问懵了!

前段时间,同事在代码中KW扫描的时候出现这样一条:上面出现这样的原因是在使用foreach对HashMap进行遍历时,同时进行put赋值操作会有问题,异常ConcurrentModificationException。于是帮同简单的看了一下,印象中集合类在进行遍历时同时进行删除或者添加操作时需要谨慎,一般使用迭代器进行操作。于是告诉同事,应该使用迭代器Iterator来对集合元素进行操作。同事问我为什么?这一下子把我问蒙了?对啊,只是记得这样用不可以,但是好像自己从来没有细究过为什么?

SpringBoot请求转发与重定向

但是可能由于B网址相对于A网址过于复杂,这样搜索引擎就会觉得网址A对用户更加友好,因而在重定向之后任然显示旧的网址A,但是显示网址B的内容。在平常使用手机的过程当中,有时候会发现网页上会有浮动的窗口,或者访问的页面不是正常的页面,这就可能是运营商通过某种方式篡改了用户正常访问的页面。重定向,是指在Nginx中,重定向是指通过修改URL地址,将客户端的请求重定向到另一个URL地址的过程,Nginx中实现重定向的方式有多种,比如使用rewrite模块、return指令等。使用场景:在返回视图的前面加上。

SSO 单点登录和 OAuth2.0 有何区别?

此方法的缺点是它依赖于浏览器和会话状态,对于分布式或者微服务系统而言,可能需要在服务端做会话共享,但是服务端会话共享效率比较低,这不是一个好的方案。在单点登录的上下文中,OAuth 可以用作一个中介,用户在一个“授权服务器”上登录,并获得一个访问令牌,该令牌可以用于访问其他“资源服务器”上的资源。首先,SSO 主要关注用户在多个应用程序和服务之间的无缝切换和保持登录状态的问题。这种方法通过将登录认证和业务系统分离,使用独立的登录中心,实现了在登录中心登录后,所有相关的业务系统都能免登录访问资源。

TCP协议-TCP连接管理

TCP协议是 TCP/IP 协议族中一个非常重要的协议。它是一种面向连接、提供可靠服务、面向字节流的传输层通信协议。TCP(Transmission Control Protocol,传输控制协议)。

接口响应慢?那是你没用 CompletableFuture 来优化!

大多数程序员在平时工作中,都是增删改查。这里我跟大家讲解如何利用CompletableFuture优化项目代码,使项目性能更佳!

30张图带你彻底理解红黑树

当在10亿数据进行不到30次比较就能查找到目标时,不禁感叹编程之魅力!人类之伟大呀!—— 学红黑树有感。终于,在学习了几天的红黑树相关的知识后,我想把我所学所想和所感分享给大家。红黑树是一种比较难的数据结构,要完全搞懂非常耗时耗力,红黑树怎么自平衡?什么时候需要左旋或右旋?插入和删除破坏了树的平衡后怎么处理?等等一连串的问题在学习前困扰着我。如果你在学习过程中也会存在我的疑问,那么本文对你会有帮助,本文帮助你全面、彻底地理解红黑树!

为什么阿里巴巴修正了HashMap关于1024个元素扩容的次数?(典藏版)

此番修正主要是每个人对「扩容」定义存在了分歧,在JDK1.8中如果没有给HashMap设置初始容量,那么在第一次put()操作的时候会进行resize()。而有的人认为这算一次扩容,有的人认为这不是一次扩容,这只是HashMap容量的初始化。所以存储1024的元素时:前者的人认为扩容次数为8次。后者的人认为扩容次数为7次。孤尽老师说对此分歧,希望用没有「二义性」的语言来表示,所以「扩容次数」修正为「resize次数」。

强烈建议你不要再使用Date类了!!!

这里就不细说修改流程了,主要说一下我们在改造的时候遇到的一些问题。(Date从现在开始)是一个糟糕的类型,这解释了为什么它的大部分内容在 Java 1.1 中被弃用(但不幸的是仍在使用)。只能说这种基础的类改起来牵一发动全身,需要从DO实体类看起,然后就是各种Converter,最后是DTO。这个改造难度不高,但是复杂度非常高,一个地方没改好,轻则接口报错,重则启动失败,非常耗费精力,真不想改。我们要改的原因很简单,我们的代码缺陷扫描规则认为这是一个必须修改的缺陷,否则不给发布,不改不行,服了。

SpringBoot 中实现订单30分钟自动取消的策略

在电商和其他涉及到在线支付的应用中,通常需要实现一个功能:如果用户在生成订单后的一定时间内未完成支付,系统将自动取消该订单。本文将详细介绍基于Spring Boot框架实现订单30分钟内未支付自动取消的几种方案,并提供实例代码。

一键部署 SpringCloud 微服务,这套流程值得学习一波儿!

一键部署 springcloud 微服务,需要用到 Jenkins K8S Docker等工具。本文使用jenkins部署,流程如下图开发者将代码push到git运维人员通过jenkins部署,自动到git上pull代码通过maven构建代码将maven构建后的jar打包成docker镜像 并 push docker镜像到docker registry通过k8s发起 发布/更新 服务 操作其中 2~5步骤都会在jenkins中进行操作。

计算机网络TCP/IP协议-从双绞线到TCP

消息响应也是同理,这种带端口的消息发送方式,其实就是UDP协议,UDP简单粗暴,但是UDP存在很多问题,所以我们需要设计一个稳定可靠的协议,TCP协议,首先,网络是不稳定的,我们发送的消息很有可能会在中途丢失,所以需要设置重试机制,当消息发送失败时重新发送,为了判断是否成功,还需要要求接收方收到消息后,必须发送确认消息,这样就可以保证消息必达,另外大段的内容发送,很容易造成部分丢失,导致全部内容都要重新发送,于是我们可以将数据分包,分成多个包发送。到这,也行你会发现了,演示中的IP地址是怎么设置的呢?

自定义参数解析器,减少10%的代码

*** 赋值调用方法* 如果为空,默认调用name()方法* 该方法必须是一个不含参数的方法,否则将会调用失败* @return*/value() : value用于绑定请求参数和方法参数名一致时的对应关系。比如user?statusNo=1。方法的参数写法如下:getUser(@EnumParam(value=“statusNo”) int status) 或者 getUser(@EnumParam() int statusNo)valueMethod() : 赋值时调用枚举中的方法。

微服务全做错了!谷歌提出新方法,成本直接降9倍!

一位DataDog的客户收到6500万美元的云监控账单的消息,也再次让业界无数人惊到了。事实上有些团队在将集中式单体应用拆分为微服务时,首先进行的往往不是建立领域模型,而只是按照业务功能将原来单体应用的一个软件包拆分成多个所谓的“微服务”软件包,而这些“微服务”内的代码高度耦合,逻辑边界不清晰,长期以来,不管大厂还是小厂,微服务都被认为是云原生服务应用程序架构的事实标准,然而2023,不止那位37signals的DHH决心下云,放弃微服务,就连亚马逊和谷歌等这些云巨头,正在带头开始革了微服务的命。