IntelliJ IDEA自定义关闭当前文件的快捷方式

前言 idea中关闭当前标签页的默认快捷键是Ctrl+F4,这个组合键在键盘上操作起来很是不方便,我们可以在设置中自定义自己习惯的快捷方式。 自定义步骤 要在 IntelliJ IDEA 中将关闭当前文件的快捷方式设置为 Alt + Q,请按照以下步骤操作:打开 IntelliJ IDEA,进入菜单栏,依次点击 “File” -> “Settings”(或者直接按下快捷键 Ctrl + Alt + S)。在弹出的设置窗口中,选择 “Keymap” 选项。在 “Keymap” 选项中,你可以搜索 “Close Active Editor” 来找到关闭当前文件的操作。你可以直接在搜索框中输入 “Close Active Editor” 来快速定位。选中 “Close Active Editor”,右键选择 “Add Keyboard Shortcut”。在弹出的对话框中,输入你想要设置的快捷键组合,即 Alt + Q。确认后关闭对话框。 如果该快捷键组合已经被占用,IntelliJ IDEA 会提示你是否覆盖。确认后即可完成设置。 如图所示(我的idea使用了汉化插件) 1.先移除默认的快捷方式 2.添加自定义快捷方式(我使用的Alt+W)

基于SSM技术的分布式销售平台设计与实现

目 录 摘 要 I Abstract II 1 绪论 1 1.1 课题研究背景与意义 1 1.2 国内外研究现状 1 1.2.1 国外研究现状 1 1.2.2 国内研究现状 2 1.3 本章小结 2 2 工程开发技术介绍 3 2.1 Web前端技术栈 3 2.1.1 HTML&CSS 3 2.1.2 jQuery 3 2.1.3 JSP 3 2.2 服务端开发技术栈 3 2.2.1 MCV开发模式 3 2.2.2 SSM框架 4 2.3 项目平台框架相关技术 5 2.4 数据库 6 2.5 本章小结 6 3 系统分析 7 3.1 可行性分析 7 3.2 功能需求分析 7 3.2.1 前端功能模块 7

Mbps、Kbps、bps 与 MB、KB、B 区别与联系

之前对带宽、网速之类的只有一个模糊认知,所以有时候测算网络性能的时候,出现偏差,这里总结一下,以防后面查看。 什么是Mbps、Kbps、bps? Mbps、Kbps、bps 是速度单位,指每秒钟传输的二进制位数(bit):bit 即比特,通常用b(小写)表示,指一位二进制位,Mbps 即 Milionbit pro second(百万位每秒);Kbps 即 Kilobit pro second(千位每秒);bps 即 bit pro second(位每秒); 换算:Milionbit =1000 Kilobit =1000000 bit;所以:1Mbps = 1000Kbps、1Kbps = 1000bit、1Mbps = 1000000bps Mbps、Kbps、bps 通常用来衡量带宽的单位,带宽是指网络传输数据的速率(能力)。 什么是MB、KB、B? MB、KB、B 不是是速度单位,指的是字节数(Byte):byte 即字节,通常用B(大写)表示,1B = 8bit;MB 即百万字节,也称兆字节;KB 即千字节;B 即字节 换算:1MB = 1024KB = 1024*1024B; 区别 通常软件上显示的速度则是指每秒种传输的字节数,而不是指带宽的传输速率,实际网速需要除以8,得到的才是理论上的下载速度。 换算:1M 带宽/1M 网卡即指 1Mbps = 1000Kbps = 1000/8KBps = 125KB/每秒,所以 1M 的带宽下载的速度一般不会超过 125KB 每秒。2M、3M带宽分别是250KBps、375KBps,其下载速度分别不会超过 250 KB、375KB 每秒。 数据传输速率的衡量单位K,是十进制含义,指的是 Kbps;但数据存储的 K,是二进制含义,指的是 KB。 数据传输速率的单位是 bit/s 记作:bps;网速的单位则是 B/s。

Linux/Ubuntu/Debian基本命令:文本操作

Linux系统真的超级好用,免费,有很多开源且功能强大的软件。尤其是Ubuntu,真的可以拯救十年前的老电脑。 下面是用于在命令行界面(Terminal)中进行文本操作的键盘快捷键, 这些快捷方式对于高效的文本编辑非常方便。 Ctrl + U:从当前位置剪切该行到行首,并将其添加到剪贴板。 如果位于行尾,则剪切整行。Ctrl + K:从当前位置剪切该行到行尾,并将其添加到剪贴板。 如果在行的开头,则剪切整行。Ctrl + W:删除光标之前的单词,将其添加到剪贴板。Ctrl + Y:从剪贴板粘贴你最近剪切的最后一个内容(撤消当前光标位置的最后一个删除)。Alt + T:交换光标前的最后两个单词。Alt + L:从光标处到单词末尾变为小写。Alt + U:从光标处到单词末尾变为大写。Alt + C:大写到从光标开始的单词末尾(如果光标位于单词开头,则为整个单词)。Alt + D:删除到从光标处开始的单词末尾(如果光标位于单词开头,则删除整个单词)。Alt + .:打印上一个命令中写入的最后一个单词。Ctrl + T:交换光标前的最后两个字符。 这些快捷方式可以加快命令行上的文本编辑和操作速度,使你的工作流程更加高效。 其中一些快捷方式可能有所不同,或者可能不适用于所有终端模拟器。

Solidity Uniswap V2 Pair中交换Token

交换意味着使用一定数量的TokenA来换取Tokenb。但我们需要一些额外的辅助服务: 1.提供实际汇率。 2.保证所有的交易都是在正确的汇率下进行的。 GitHub - XuHugo/solidityproject: DApp go go go !!! 我们在研究流动性供应时学到了一些关于 DEX 定价的知识:决定汇率的是池中的流动性数量。成功互换的主要条件:互换后的reserve乘积必须等于或大于互换前的reserve乘积。无论Pool中的reserve数量是多少,恒等乘积都必须保持不变。这基本上是我们必须保证的唯一条件,而且令人惊讶的是,这个条件让我们无需计算互换价格。 正如我在介绍中提到的,Pair合约是一个核心合约,这意味着它的功能必须尽可能底层化和最小化。这也影响到我们如何向合约发送代币。有两种方法可以将代币转移给他人: 1、调用Token合约的transfer方法,并传递接收者的地址和要发送的金额。 2、调用 approve 方法,将一定数量的代币授权,允许其他用户或合约使用。其他人必须调用 transferFrom 才能转移你的Token。你只需为批准一定数量的Token支付费用,而对方则需为实际转账支付费用。 调用 approve 模式在以太坊应用中非常常见:dapp 要求用户批准最大金额的消费,这样用户就不需要一次又一次地调用批准。这可以改善用户体验。而这并不是我们目前需要考虑的,因此,我们将采用手动转入Pair合约的方式。 函数入参需要两个输出金额,每个token一个。这些是调用者希望用token换取的金额。为什么要这样做呢——需要两个token?因为我们不想强制执行交换的方向:调用者可以指定任一个金额或两个金额,我们只需执行必要的检查。 function swap( uint256 amount0Out, uint256 amount1Out, address to ) public { if (amount0Out == 0 && amount1Out == 0) revert InsufficientOutputAmount(); ... 接下来,我们需要确保有足够的reserve发送给用户。 ... (uint112 reserve0_, uint112 reserve1_, ) = getReserves(); if (amount0Out > reserve0_ || amount1Out > reserve1_) revert InsufficientLiquidity(); ... 在获得reserve并进行预检查后,我们要做的第一件事就是将token转移给用户。有趣的是,我们可以提前做这件事,反而是未了更安全,后边我们会介绍原因,也许你现在就知道了原因。转账完成后,我们再计算输入金额:

mybatis-plus 主键自增必须加@TableId(type = IdType.AUTO)注解吗

背景 使用mybatisPlus进行数据库自增,mysql 问题 MySQL的表是主键自增 bigint。 但是java bean的id属性没有加@TableId(type = IdType.AUTO)注解 用baseMapper insert之后 发现id不是从1开始的自增,而是类UUID的一串随机数 原因 百度说是因为不指定@TableId(type = IdType.AUTO) 会默认生成雪花算法,也就是一长串随机数,类UUID 解决 mybatisPlus使用要加@TableId(type = IdType.AUTO)注解

动态引用组件 <component :is=“componentName“ />

在工作中常常会引用很多组件,如: import com1 from '@/components/com1' import com2 from '@/components/com2' import com3 from '@/components/com3' .... 然后节点 <com1 /> <com2 /> <com2 /> 代码臃肿不说,而且不灵活 使用动态组件来解决 <component :is="componentFun" /> methods: { componentFun(){ // 此处可以灵活传组件路径名为值,做到用什么就传什么 let com1 = 'components/com1' return require('@/' +com1 ).default } } 也可使用for <template> <div v-for(item,index) in list :key="index"> <component :is="componentFun(item)" /> </div> </template> methods: { componentFun(item){ // 此处可以灵活传组件路径名为值,做到用什么就传什么 let com1 = item.components; // 'components/com1' return require('@/' +com1 ).default }

浅谈 v-bind=“$props“、v-bind=“$attrs“、v-on=“$listeners“的关系用法

父级A----->子级B----->孙级C 传值 目标是父级属性传递给孙级,解决A传B传C繁琐传值问题 方法一:使用 $attrs 父级A <father name="张三" age="50" /> 子级B 无需使用 Props 接收,它会把父级传递过来的name、age 都传给 孙级 在子级B里面引用孙级C <Sun v-bind="$attrs" /> 在孙级C里使用Props 接收 props:['name','age'] 方法二:使用 $props 不同在于要什么就拿什么,没有在子级B里接收则在孙级C就不会有! 需要在子级B里 接收 props:['name'] 在孙级C里使用Props 接收 props:['name'] v-on="$listener 是接收孙级C方法事件 在孙级C里 使用 this.$emit('sendFun', '爷爷你好!') 在子级B里 的孙级组件 <Sun v-bind="$attrs" v-on="$listeners"/>,子级B不再需要添加任务方法 在父级响应方法就可 <father name="张三" age="50" @sendFun="sendFun"></father>

SpringBoot 手写 Starter

1.介绍 SpringBoot中的starter是一种非常重要的机制,能够抛弃以前繁杂的配置,将其统一集成进starter,应用者只需要在maven中引入starter依赖,SpringBoot就能自动扫描到要加载的信息并启动相应的默认配置。starter让我们摆脱了各种依赖库的处理,需要配置各种信息的困扰。SpringBoot会自动通过classpath路径下的类发现需要的Bean,并注册进IOC容器。SpringBoot提供了针对日常企业应用研发各种场景的spring-boot-starter依赖模块。所有这些依赖模块都遵循着约定成俗的默认配置,并允许我们调整这些配置,即遵循“约定大于配置”的理念。 优点 一般认为,SpringBoot 微框架从两个主要层面影响 Spring 社区的开发者们: 基于 Spring 框架的“约定优先于配置(COC)”理念以及最佳实践之路。 提供了针对日常企业应用研发各种场景的 spring-boot-starter 自动配置依赖模块,如此多“开箱即用”的依赖模块,使得开发各种场景的 Spring 应用更加快速和高效。 ​ SpringBoot 提供的这些“开箱即用”的依赖模块都约定以 spring-boot-starter- 作为命名的前缀,并且皆位于 org.springframework.boot 包或者命名空间下(虽然 SpringBoot 的官方参考文档中提到不建议大家使用 spring-boot-starter- 来命名自己写的类似的自动配置依赖模块,但实际上,配合不同的 groupId,这不应该是什么问题)。 2.starter自定义 springboot 官方建议springboot官方推出的starter 以spring-boot-starter-xxx的格式来命名,第三方开发者自定义的starter则以xxxx-spring-boot-starter的规则来命名,事实上,很多开发者在自定义starter的时候往往会忽略这个东西。 自定义一个登录拦截的启动器,authority-spring-boot-starter 开发步骤: 2.1新建工程 引入以下依赖: <!--自定义启动器 必须依赖的包--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> 2.2创建登录拦截器 import org.springframework.web.servlet.HandlerInterceptor; public class AuthorityInteceptor implements HandlerInterceptor { public boolean preHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler) throws Exception { System.

【开源】JAVA+Vue.js实现智能教学资源库系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课程资源模块2.4 课程作业模块2.5 课程评价模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 课程档案表3.2.2 课程资源表3.2.3 课程作业表3.2.4 课程评价表 四、系统展示五、核心代码5.1 新增课程评价5.2 生成课程作业5.3 新增课程资源5.4 查询课程5.5 新增课表 五、免责说明 一、摘要 1.1 项目介绍 基于JAVA+Vue+SpringBoot+MySQL的智能教学资源库系统,包含了课程管理、资源中心、授课中心、作业发布、课程评价、课程质量分析模块,还包含系统自带的用户管理、部门管理、角色管理、菜单管理、日志管理、数据字典管理、文件管理、图表展示等基础模块,智能教学资源库系统基于角色的访问控制,给高校管理员、教师和学生角色使用,可将权限精确到按钮级别,您可以自定义角色并分配权限,系统适合设计精确的权限约束需求。 1.2 项目录屏 二、功能模块 近年来,计算机技术、网络技术的迅猛发展,给传统办学提供了新的模式。绝大部分大学和学院都已介入互联网领域,并建成校园网,各校的硬件设施也已经比较完善。通过设计网络拓扑架构、数据库基础结构,建设网络安全系统、信息共享与管理系统、信息的发布与管理系统,方便了管理者、老师和学生间的信息发布、信息交流和信息共享。以现代计算机技术、网络技术为基础的数字化教学,主要是朝着信息化、网络化、现代化的目标迈进。 本文设计的课程资源库管理系统的包括了系统数据中心模块,用来存放管理系统通用的模块,另外分别设计了课程档案模块、课程资源模块、课程作业模块、课程评价模块、授课管理模块和学习质量分析模块这六大模块,用于存放系统的核心业务逻辑。 2.1 数据中心模块 数据中心模块包含了对课程资源库管理系统的基础模块,比如管理谁可以登录这套系统,记录这些人登录系统做了什么,不同的人拥有不同权限的管理。 2.2 课程档案模块 课程档案模块用于对课程的数据进行管理,其中包括课程标题、课程介绍、课程图片、课程状态、创建人、创建时间、更新人、更新时间等,可以通过此模块对课程数据进行添加、编辑更新、删除、查询操作。 2.3 课程资源模块 课程资源管理模块是对课程的资源信息进行管理,课程有了资源才能更好的被学生所接受,课程资源的字段包括课程ID、课程名称、资源名称、文件、创建人、创建时间、更新人、更新时间等,教师可以新增课程的资源数据,学生可以查询教师发布的课程资源信息。 2.4 课程作业模块 课程作业模块是为了管理课程的作业数据,有了课程后,教师可以发布指定课程的作业数据,支持一键生成课程作业,其中课程作业的字段包括课程ID、课程名称、作业名称、作业附件、完成附件、学生ID、学生姓名、创建人等,教师可以增加、删除、编辑和条件查询课程作业,学生可以提交属于自己的作业数据。 2.5 课程评价模块 课程评价模块是维护关于课程的评价信息,学生学习完课程后,可以对课程进行评价,撰写评语,以便于改进课程的质量。其中课程评价字段包括课程ID、课程名称、评价人、评价内容、评价时间、备注、创建人、创建时间等,学生可以增加、删除、编辑和条件查询自己的课程评价,教师可以查询课程的评价内容。 三、系统设计 3.1 用例设计 3.2 数据库设计 3.2.1 课程档案表 3.2.2 课程资源表 3.2.3 课程作业表 3.2.4 课程评价表 四、系统展示 五、核心代码 5.1 新增课程评价 @RequestMapping(value = "/addOne", method = RequestMethod.

HTML静态网页成品作业(HTML+CSS)——原神介绍设计制作(4个页面)

🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTML+CSS,未使用Javacsript代码,共有4个页面。 二、作品演示 三、代码目录 四、网站代码 HTML部分代码 <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>原神首页</title> <link rel="stylesheet" href="./css/css.css"> </head> <body> <main> <header> <img src="./img/header_img.jpg" alt="" id="header_img"> </header> <section class="f"> <aside> <ul> <li class="t"><a href="index.html">游戏首页</a></li> <li><a href="youxijianjie.html">游戏简介</a></li> <li><a href="youxixitong.html">游戏系统</a></li> <li><a href="youxidenglu.html">游戏登录</a></li> </ul> <img src="./img/nav_bottom.jpg" id="nav_bottom" alt=""> </aside> <section class="z"> <header>基本信息</header> <table border="1"> <tr> <th>中文名</th> <td>原神</td> <th>玩家人数</th> <td>1 人(联机时上限4人)</td> </tr> <tr> <th>原版名称</th> <td>原神Project</td> <th>游戏画面</th> <td>3D</td> </tr> <tr> <th>别 名</th> <td>Genshin Impact 、원신</td> <th>游戏引擎</th> <td>Unity</td> </tr> <tr> <th>游戏类型</th> <td>角色扮演</td> <th>最新版本</th> <td>3.

在Linux系统创建文件目录及其内部文件

在Linux或类Unix系统中,touch命令通常用来创建新的空文件或者更新现有文件的访问和修改时间戳。如果你想要强制创建一个文件(即使文件已经存在或者父目录不存在),touch命令默认行为就是如果文件不存在则创建,并不会询问用户是否要覆盖已存在的文件。 touch filename 上面的命令会创建一个名为filename的新文件,如果文件不存在的话。即使文件权限导致你没有写入权限,touch命令也不会“强制”创建文件,它会根据系统的权限设置来执行操作。如果你需要在父目录不存在的情况下也创建文件,你需要首先确保你有创建该目录及文件所需的权限,然后可以先创建父目录再使用touch命令: mkdir -p $(dirname filename) && touch filename 上述命令中,mkdir -p参数会创建多级目录(如果它们还不存在的话),然后再尝试创建文件。但请注意,如果由于权限问题无法创建目录,这个命令也会失败。 在某些情况下,如果目标路径受权限限制或其他安全措施影响,可能需要使用sudo来提升权限: sudo mkdir -p $(dirname filename) && sudo touch filename 但是,请谨慎使用sudo,因为它允许以超级用户(root)身份执行命令,可能会对系统造成重大更改。

MySQL 的基础操作

数据库的基础操作 1. 库操作2. 表的操作3. 数据类型 数据库是现代应用程序中至关重要的组成部分,通过数据库管理系统(DBMS)存储和管理数据。 1. 库操作 创建数据库 创建数据库是开始使用数据库的第一步。下面是一些常见的创建数据库的示例: -- 创建名为 db1 的数据库,使用 utf8 字符集 CREATE DATABASE db1 DEFAULT CHARACTER SET utf8; -- 创建名为 db2 的数据库,指定字符集为 utf8 CREATE DATABASE db2 CHARSET=utf8; -- 创建名为 db3 的数据库,指定字符集为 utf8,校验规则为 utf8_general_ci CREATE DATABASE db3 CHARSET=utf8 COLLATE utf8_general_ci; 查看系统默认字符集和校验规则 您可以使用以下命令查看系统默认字符集和校验规则: SHOW VARIABLES LIKE 'character_set_database'; SHOW VARIABLES LIKE 'collation_database'; 查看数据库支持的字符集和校验规则 您可以使用以下命令查看数据库支持的字符集和校验规则: SHOW CHARSET; SHOW COLLATION; 查看数据库 您可以使用以下命令查看当前数据库中的所有数据库: SHOW DATABASES; 显示数据库创建语句 您可以使用以下命令显示数据库的创建语句: SHOW CREATE DATABASE database_name; 修改数据库

Koa: 打造高效、灵活的Node.js后端 (介绍与环境部署)

在上一篇文章中,我们了解了Node.js的基础知识,今天我们将进一步学习Node.js 较新的一个轻量级Web框架Koa,一起创建NodeJS后端服务器吧! 一、介绍 Koa是一个新生代Node.js Web框架,由Express原团队成员开发,它的设计目标是成为一个更小、更富有表现力、更健壮的Web框架。相比于Express,Koa具有以下特点: 中间件机制:Koa的中间件机制更加简洁、灵活,可以更好地控制请求和响应的流程。异步流程控制:Koa使用async/await来处理异步操作,使得代码更加简洁、易读。轻量级:Koa本身很小,只提供了最基本的功能,其他功能都可以通过中间件来扩展。高度可定制:Koa没有强制性的中间件,开发者可以自由选择和定制中间件来满足自己的需求。 最后,我们还会用Koa-generate进行Koa标准项目生成!😲🎉 二、内容 1.环境搭建 首先,我们需要确保已经安装了Node.js和npm,然后使用npm安装Koa: npm install koa --save 推荐Node版本大于12 2.实例 接下来,我们来创建一个简单的Koa应用,代码如下: const Koa = require('koa'); const app = new Koa(); app.use(async (ctx) => { ctx.body = '我是GISer Liu,为成为全栈GIS开发者而奋斗'; }); app.listen(3000, () => { console.log('Server is running at http://localhost:3000'); }); 注意:这里使用了async/await来处理请求,ctx是Koa提供的上下文对象,我们可以通过它来控制请求和响应。 代码解释: const Koa = require('koa');:引入Koa模块,并将其赋值给常量Koa。const app = new Koa();:创建一个新的Koa应用实例,并将其赋值给常量app。app.use(async (ctx) => {});:为Koa应用注册一个中间件,中间件是一个异步函数,接受一个上下文对象ctx作为参数。在函数体内,通过为ctx.body赋值,来设置响应体的内容为"Hello World"。ctx.body = 'Hello World';:将上下文对象ctx的body属性设置为"Hello World",该属性将成为响应体的内容。app.listen(3000, () => {});:启动Koa应用,监听3000端口,一旦监听成功,就执行回调函数。console.log('Server is running at <http://localhost:3000>');:在回调函数中,输出一条日志,提示服务器已经启动,并且可以通过http://localhost:3000访问。 在Koa中,很重要的三大对象就是Context、Request、Response,我们可以输出ctx看看对象构造;

K8S之实现业务的金丝雀发布

如何实现金丝雀发布 金丝雀发布简介优缺点在k8s中实现金丝雀发布 金丝雀发布简介 金丝雀发布的由来:17 世纪,英国矿井工人发现,金丝雀对瓦斯这种气体十分敏感。空气中哪怕有极其微量的瓦斯,金丝雀也会停止歌唱;当瓦斯含量超过一定限度时,虽然人类毫无察觉,金丝雀却早已毒发身亡。当时在采矿设备相对简陋的条件下,工人们每次下井都会带上一只金丝雀作为瓦斯检测指标,以便在危险状况下紧急撤离。 金丝雀发布(又称灰度发布、灰度更新):一般先发1台,或者一个小比例,例如2%的服务器,主要做流量验证用,也称为金丝雀 (Canary) 测试 (国内常称灰度测试)。 简单的金丝雀测试一般通过手工测试验证,复杂的金丝雀测试需要比较完善的监控基础设施配合,通过监控指标反馈,观察金丝雀的健康状况,作为后续发布或回退的依据。 如果金丝测试通过,则把剩余的V1版本全部升级为V2版本。如果金丝雀测试失败,则直接回退金丝雀,发布失败。 优缺点 优点:灵活,策略自定义,可以按照流量或具体的内容进行灰度(比如不同账号,不同参数),出现问题不会影响全网用户 缺点:没有覆盖到所有的用户导致出现问题不好排查 在k8s中实现金丝雀发布 实践描述: 一个服务部署6个pod,更新了部分pod里服务的版本:用的新的代码做的镜像,通过测试再更新剩余的。 1、创建资源 vim myapp.yaml apiVersion: apps/v1 kind: Deployment metadata: name: myapp namespace: canary spec: replicas: 6 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp-container image: janakiramm/myapp:v1 imagePullPolicy: IfNotPresent ports: - containerPort: 80 在终端1更新服务并监测更新过程 kubectl apply -f myapp.yaml kubectl get pods -l app=myapp -n canary -w 2、开始升级一个服务 打开另一个终端2执行如下操作:

K8S之实现业务的蓝绿部署

如何实现蓝绿部署 什么是蓝绿部署?蓝绿部署的优势和缺点优点缺点 通过k8s实现线上业务的蓝绿部署 什么是蓝绿部署? 部署两套系统:一套是正在提供服务系统,标记为 “绿色” ;另一套是准备发布的系统,标记为 “蓝色”。 两套系统都是功能完善的、正在运行的系统,只是系统版本和对外服务情况不同。 要用开发的新版本替换线上的旧版本,除了已上线运行的系统之外,再搭建一个使用新版本代码的全新系统。这时候,一共有两套系统在运行,正在对外提供服务的老系统是绿色系统,新部署的系统是蓝色系统。 蓝色系统 用来做发布前测试,测试过程中发现任何问题,可以直接在蓝色系统上修改,不干扰用户正在使用的系统。(ps. 两套系统没有耦合的时候才能百分百保证不干扰) 蓝色系统经过反复的测试、修改、验证,确定达到上线标准之后,直接将用户切换到蓝色系统。 切换后的一段时间内,依旧是蓝绿两套系统并存,但是用户访问的已经是蓝色系统。这段时间内观察蓝色系统(新系统)工作状态,如果出现问题,直接切换回绿色系统。 当确信对外提供服务的蓝色系统工作正常,不对外提供服务的绿色系统已经不再需要的时候,蓝色系统正式成为对外提供服务系统,成为新的绿色系统。 原先的绿色系统可以销毁,将资源释放出来,用于部署下一个蓝色系统。 蓝绿部署的优势和缺点 优点 更新过程无需停机,风险较少回滚方便,只需要更改路由或者切换DNS服务器,效率较高 缺点 成本较高,需要部署两套环境。在非隔离的机器(Docker、VM)上操作时,可能会导致蓝绿环境被摧毁风险负载均衡器/反向代理/路由/DNS处理不当,将导致流量没有切换过来情况出现 通过k8s实现线上业务的蓝绿部署 方式:创建deployment,然后更新应用程序的service以指向对应deployment部署的应用 实践说明:将项目老版本(v1)代码和新版本(v2)代码做成不同的镜像。 实践步骤: 1、创建绿色部署环境(基于v1版本做的镜像) 通过deployment来创建运行pod vim green.yaml 编写Deployment资源文件 apiVersion: apps/v1 kind: Deployment metadata: name: myapp-v1 namespace: blue-green spec: replicas: 3 selector: matchLabels: app: myapp version: v1 template: metadata: labels: app: myapp version: v1 spec: containers: - name: myapp image: janakiramm/myapp:v1 imagePullPolicy: IfNotPresent ports: - containerPort: 80 使用kubectl命令创建部署

SpringBoot项目集成Redis+JWT实现系统登录token校验

原理 用户登录系统时,后端拿到账号密码进行登录校验(查询数据库),校验通过生成token返回给前端,并放行请求的资源后续前端每次请求后端接口时,都在请求头中带上token,后端的全局拦截器拦截到请求,去redis查询缓存的token,找到对应token则放行请求到对应接口方法,否则返回未登录提醒。 pom文件中引入依赖(gradle同样) <!-- Redis 相关依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- JWT 相关依赖 --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.11.2</version> </dependency> 配置redis # Redis 连接配置 spring.redis.host=localhost spring.redis.port=6379 spring.redis.password=your_redis_password JWT Token 生成校验工具 import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.stereotype.Component; import java.util.Date; @Component public class JwtTokenUtil { private static final String SECRET_KEY = "your_secret_key"; private static final long EXPIRATION_TIME = 86400000; // 10 days public String generateToken(String username) { return Jwts.builder() .

Linux:kubernetes(k8s)探针LivenessProbe的使用(9)

他做的事情就是当我检测的一个东西他不在规定的时间内存在的话,我就让他重启,这个检测的目标可以是文件或者端口等 我这个是在上一章的基础之上继续操作,我会保留startupProbe探针让后看一下他俩的执行优先的一个效果 Linux:kubernetes(k8s)探针StartupProbe的使用(8)-CSDN博客https://blog.csdn.net/w14768855/article/details/136544481?spm=1001.2014.3001.5501 1.探针目标:错误的请求接口 apiVersion: v1 # api文档版本 kind: Pod # 资源对象类型 metadata: # pod相关的元数据,用于描述pod的数据 name: nginx-po # pod名称 labels: # pod的标签 type: app #这个是随便写的 自定义的标签 version: 1.0.0 #这个是随便写的 test: 1.0.0 #都标签随便写的 namespace: 'default' #命名空间的配置 spec: #期望pod按照这里面的描述进行创建 containers: #对于pod容器的描述 - name: nginx #容器的名称 image: nginx:1.7.9 # 指定容器的镜像 imagePullPolicy: IfNotPresent #镜像拉取策略 startupProbe: #应用容器探针 # httpGet: # 探测方式 # path: /index.html #http 请求路径 # tcpSocket : # port: 80 # 请求端口 exec: command: - sh - -c - "

C语言从入门到精通 第十一章(文件操作)

写在前面: 本系列专栏主要介绍C语言的相关知识,思路以下面的参考链接教程为主,大部分笔记也出自该教程。除了参考下面的链接教程以外,笔者还参考了其它的一些C语言教材,笔者认为重要的部分大多都会用粗体标注(未被标注出的部分可能全是重点,可根据相关部分的示例代码量和注释量判断,或者根据实际经验判断)。如有错漏欢迎指出。 参考教程:C语言程序设计从入门到进阶【比特鹏哥c语言2024完整版视频教程】(c语言基础入门c语言软件安装C语言指针c语言考研C语言专升本C语言期末计算机二级C语言c语言_哔哩哔哩_bilibili 一、概述 1、为什么使用文件 使用文件我们可以将数据直接存放在电脑的硬盘上,做到数据的持久化。 2、什么是文件 磁盘上的文件是文件,但是在程序设计中,一般涉及到的文件有两种:程序文件、数据文件(从文件功能的角度来分类)。 (1)程序文件: 包括源程序文件(后缀为.c)、目标文件(windows环境后缀为.obj)、可执行程序(windows环境后缀为.exe)。 (2)数据文件: 文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件,本章讨论的是数据文件。 在以前各章所处理数据的输入输出都是以终端为对象的,即从终端的键盘输入数据,运行结果显示到显示器上。其实有时候需要把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使用,这时处理的就是磁盘上文件。 3、文件名 (1)一个文件要有一个唯一的文件标识,以便用户识别和引用。 (2)文件名包含文件路径、文件名主干、文件后缀3部分,例如“c:\code\test.txt”。 二、文件的打开和关闭 1、文件指针 (1)缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。 (2)每个被使用的文件都会在内存中开辟了一个相应的文件信息区用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等),这些信息是保存在一个结构体变量中的,该结构体类型是有系统声明的,取名FILE。不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异,如VS2013编译环境提供的stdio.h头文件中有以下的文件类型声明: struct _iobuf { char *_ptr; int _cnt; char *_base; int _flag; int _file; int _charbuf; int _bufsiz; char *_tmpfname; }; typedef struct _iobuf FILE; (3)每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。 (4)可以创建一个FILE*类型的指针变量——“FILE* pf;”定义pf是一个指向FILE类型数据的指针变量,使pf指向某个文件的文件信息区(一个结构体变量),通过该文件信息区中的信息就能够访问该文件,也就是说,通过文件指针变量能够找到与它关联的文件。 2、文件的打开和关闭 (1)文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。 (2)在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。 (3)ANSIC规定使用fopen函数来打开文件,使用fclose函数来关闭文件。(mode是文件的打开方式) //打开文件 FILE * fopen ( const char * filename, const char * mode ); //只读文件时如果找不到文件,会返回一个空指针 //关闭文件 int fclose ( FILE * stream );