首页 文章 精选 留言 我的

精选列表

搜索[Java],共10000篇文章
优秀的个人博客,低调大师

利用ansible-playbook从测试环境获取tomcat中java项目新版本发布到生产环境

一、环境描述 安装有ansible的服务器:192.168.13.45 测试环境服务器:192.168.13.49 /home/app/api-tomcat/webapps/api.war为测试环境新版本war包位置 生产环境服务器:192.168.13.51 /home/app/api-tomcat/webapps/api.war为生产环境war包位置 /home/app/api-tomcat/webapps/api为生产环境项目位置 /home/app/tomcat.bak/api/webapps-时间戳,为老版本webapps备份位置 /home/app/newwar/api.war为从测试环境获得的新版本war包临时存放位置 /home/app/newwar/api为新版本war包解压后临时存放的位置 全部以app用户执行 二、编写ansible-playbook用的yml文件 1、升级 这里所有的#开头的注释文字在使用的时候都要去掉,因为yml是没有注释的 #生产环境主机的ip,这里也可以是/etc/ansible/hosts定义的组名 -hosts:192.168.13.51 #变量,在yml文件中使用变量可以使整个文件可以用在不同的主机上升级,变量的使用方法是,如果task中的变量在冒号后则一定要将冒号后整句加上双引号"",因为yml文件自动把冒号后的大括号的内容识别为列表,如shell:"/bin/startup.sh" vars: #测试环境IP地址 testIP:192.168.13.49 #测试环境中项目的位置 testhome:/home/app/api-tomcat/webapps #测试环境中项目war包的名字 warname:api.war #生产环境中项目的tomcat所在的位置 oldhome:/home/app/api-tomcat #生产环境中老版本项目所在webapps备份目录的位置 backupwebapps:/home/app/tomcat.bak #从测试环境获取的新版本war包所在的位置 newwar:/home/app/newwar #新版本war包解压后目录的名字 zipname:api #整个远程自动化操作中所使用的账户,这里整个从生产环境到测试环境的操作都是用app用户执行的 remote_user:app #具体操作 tasks: -name:生产环境删除/home/app/newwar目录,若目录不存在则忽略错误(删这个目录的原因是因为之后要新建这个目录,确保整个yml文件可以多次执行,ignore_errors为是否忽略错误返回值) file:path=state=absent ignore_errors:yes -name:生产环境创建/home/app/newwar目录,改权限,(其中recurse是递归创建目录,state是文件类型为目录) file:path=recurse=yesmode=775owner=appgroup=appstate=directory -name:从测试环境192.168.13.49复制新版本/home/app/api-tomcat/webapps/api.war包到生产环境192.168.13.51的/home/app/newwar目录下,此处之后的操作都是在生产环境下 shell:scpapp@:/ -name:给/home/app/newwar递归改权限(因为整改操作都是以app用户身份执行的,所以一定要保证权限为app的权限) file:dest=recurse=yesmode=775owner=appgroup=app -name:解压/home/app/newwar/api.war包在/home/app/newwar/api目录 shell:unzip-oq/-d/ -name:再次给/home/app/newwar递归改权限(确保新版本为app的权限) file:dest=recurse=yesmode=775owner=appgroup=app -name:创建用来备份老版本webapps的目录/home/app/tomcat.bak/api并改递归权限 file:path=/recurse=yesmode=775owner=appgroup=appstate=directory -name:备份/home/app/api-tomcat/webapps到目录/home/app/tomcat.bak/api/webapps-时间戳(这个备份目录是用来回滚的) shell:cp-a/webapps//webapps-`date+%Y%m%d%H%M` -name:kill进程方式停止服务.忽略错误返回值(用这种方式才能确保老版本停止运行,否则会出现冲突) shell:ps-ef|grep|grep-vgrep|xargskill ignore_errors:yes -name:kill进程方式停止服务.忽略错误返回值(再次确保老版本不再运行) shell:ps-ef|grep|grep-vgrep|xargskill ignore_errors:yes -name:再次kill进程方式停止服务.忽略错误返回值 shell:ps-ef|grep|grep-vgrep|xargskill ignore_errors:yes -name:查看停止服务的结果,进程是否还在 shell:ps-ef|grep -name:删除老版本的/home/app/api-tomcat/webapps/api.war包 file:path=/webapps/state=absent ignore_errors:yes -name:删除老版本的/home/app/api-tomcat/webapps/api程序目录 file:path=/webapps/state=absent ignore_errors:yes -name:复制新版本目录/home/app/newwar/api到/home/app/api-tomcat/webapps目录下 shell:cp-a//webapps/ -name:复制新版本war包/home/app/newwar/api.war包到/home/app/api-tomcat/webapps目录下 shell:cp-a//webapps/ -name:启动服务/home/app/api-tomcat/bin/startup.sh(source是为了载入jdk的环境变量,nohup是为了保证yml跑完了进程依然不退出) shell:"source/etc/profile;nohup/bin/startup.sh&" -name:查看进程中是否存在启动的服务 shell:ps-ef|grep 2、回滚 #生产环境主机地址 -hosts:192.168.13.51 #变量和升级的相同 vars: testIP:192.168.13.49 testhome:/home/app/api-tomcat/webapps warname:api.war oldhome:/home/app/api-tomcat backupwebapps:/home/app/tomcat.bak newwar:/home/app/newwar zipname:api #远程操作依然使用app用户 remote_user:app #以下操作都是在生产环境中进行 tasks: -name:kill进程方式停止服务.忽略错误返回值 shell:ps-ef|grep|grep-vgrep|xargskill ignore_errors:yes -name:kill进程方式停止服务.忽略错误返回值 shell:ps-ef|grep|grep-vgrep|xargskill ignore_errors:yes -name:再次kill进程方式停止服务.忽略错误返回值 shell:ps-ef|grep|grep-vgrep|xargskill ignore_errors:yes -name:查看停止服务的结果.进程是否还在 shell:ps-ef|grep -name:删除/home/app/api-tomcat/webapps目录 file:path=/webappsstate=absent -name:显示/home/app/tomcat.bak/api/中最新备份的webapps目录,目录名应该是webapps-最近时间戳 shell:ls-r/|head-1 -name:复制备份的/home/app/tomcat.bak/api/webapps-最新时间戳,到项目并改名/home/app/api-tomcat/webapps shell:cp-a//$(ls-r/|head-1)/webapps -name:启动服务/home/app/api-tomcat/bin/startup.sh shell:"source/etc/profile;nohup/bin/startup.sh&" -name:删除刚才回滚的备份文件 shell:rm-rf//$(ls-r/ -name:查看进程中是否存在启动的服务 shell:ps-ef|grep 三、升级操作和注意事项 1、升级前免密钥操作 ansible所在主机192.168.13.45 #在app用户下生成密钥 ssh-keygen-trsa #发送公钥到测试环境 ssh-copy-id-i.ssh/id_rsa.pubapp@192.168.13.49 #发送公钥到生产环境 ssh-copy-id-i.ssh/id_rsa.pubapp@192.168.13.51 生产环境主机192.168.13.51 #在app用户下生成密钥 ssh-keygen-trsa #发送公钥到测试环境 ssh-copy-id-i.ssh/id_rsa.pubapp@192.168.13.49 为了业务安全,ansible所在主机和生产环境主机、测试环境主机是互通的。生产环境主机能连上测试环境主机,但测试环境主机不能连上生产环境主机,所以这里测试环境主机不需要将密钥发送给生产环境主机 2、升级和回滚 升级 ansible-playbook/home/app/api.yml-v 回滚 ansible-playbook/home/app/api-rollback.yml-v ansible-playbook后面跟上之前写的yml文件路径,-v是为了显示详细执行信息 3、注意 如果在jenkins中执行升级和回滚的yml文件,一定要将在jenkins用户的公钥发送给生产环境主机和测试环境主机,否则会报权限错误 要操作的主机一定要填入/etc/ansible/hosts中 两个yml文件已在生产环境中验证

优秀的个人博客,低调大师

验证码字符与算术题,这个Java工具类6个方法只产字符串

## 📋 目录 - [一、工具类功能](#sec-func) - [二、所需环境](#sec-env) - [三、方法与调用示例(按需调用)](#sec-method) ## 一、工具类功能 生成短信码、邮箱码与图形码上要印的那串字符,另出「3 + 5 = ?」这类算术题,四类字符集各有剔除口径,随机源是共享的 `SecureRandom`,本类只产字符串、不负责画图。 ## 二、所需环境 JDK 17或以上 ## 三、方法与调用示例(按需调用) 🔢 **方法序号**:1 🎯 **方法用途**: - 生成纯数字验证码,短信码、邮箱一次性码这类只要数字的场景直接用它 - 要印在图形码上的那串文本也可以先拿它出码,再交给画图的那一步 🧩 **方法定义**:`public static String digits(int length)` 🗣️ **入参解释**:`public static String digits(字符长度)` 📤 **返回值解释**:`String`,指定长度的数字串 💡 **边界口径**: - 字符集是完整的 0 到 9 共 10 个数字,首位同样可为 0 - 不剔除易混字符,要避开 0 与 1 走 `mixed` - 长度必须落在 1 到 128,越界抛 `IllegalArgumentException` 并带上实际值 - 随机源是类内共享的 `SecureRandom`,多线程直接并发调用,别换成 `Random` 或 `Math.random()` 🧪 **方法示例**: - `digits(6)` 拿到 `013803`,首位就是 0 - `digits(6)` 再拿一次是 `864326`,同一个长度每次给出的码不同 - 循环 500 轮取 `digits(6)` 的首位判 0,拿到 `true`,首位为 0 的组合确实会出现 - 连跑 500 次 `digits(6).matches("[0-9]{6}")` 拿到 `true` - `digits(0)` 抛 `长度必须大于0,当前为0` - `digits(129)` 抛 `长度不能超过128,当前为129` --- 🔢 **方法序号**:2 🎯 **方法用途**: - 生成大写字母验证码,字符集去掉易混的 I 与 O,保留 L - 券码、邀请码这种要人肉眼辨认的场合用纯字母比混数字好认 🧩 **方法定义**:`public static String upperLetters(int length)` 🗣️ **入参解释**:`public static String upperLetters(字符长度)` 📤 **返回值解释**:`String`,指定长度的大写字母串 💡 **边界口径**: - 字符集是去掉 I、O 的 24 个大写字母 - 长度的校验口径与 `digits` 一致,上限 128 - 串里不会出现数字,也不区分小写形态 🧪 **方法示例**: - `upperLetters(4)` 拿到 `SMSG`,样本值每次跑都不一样 - 连跑 500 次 `upperLetters(8).matches("[A-HJ-NP-Z]{8}")` 拿到 `true`,I 与 O 一次都没出现 --- 🔢 **方法序号**:3 🎯 **方法用途**: - 生成小写字母验证码,字符集去掉 i、l、o 这三个易混字符 - 页面上一串小写码、和大小写无关的口令提示用这一版 🧩 **方法定义**:`public static String lowerLetters(int length)` 🗣️ **入参解释**:`public static String lowerLetters(字符长度)` 📤 **返回值解释**:`String`,指定长度的小写字母串 💡 **边界口径**: - 字符集是去掉 i、l、o 的 23 个小写字母,j、k、m、n、p 都保留 - 长度校验与上限同 `digits` - 与大写版互不相干,要大小写都有走 `mixed` 🧪 **方法示例**: - `lowerLetters(6)` 拿到 `nxccjr`,样本值每次跑都不一样 - 连跑 500 次 `lowerLetters(8).matches("[a-hj-kmnp-z]{8}")` 拿到 `true` --- 🔢 **方法序号**:4 🎯 **方法用途**: - 生成数字加大小写字母的混合码,同长度下空间比单一字符集大得多 - 图形验证码上要印的那串文本、需要短而强的凭证时用这一版 🧩 **方法定义**:`public static String mixed(int length)` 🗣️ **入参解释**:`public static String mixed(字符长度)` 📤 **返回值解释**:`String`,指定长度的混合字符串 💡 **边界口径**: - 字符集共 54 个:数字去掉 0 与 1,大写去掉 I、L、O,小写去掉 i、l、o - 结果区分大小写,校验时要按大小写敏感处理,或者自己先统一大小写 - 长度上限同样是 128,越界抛 `IllegalArgumentException` 🧪 **方法示例**: - `mixed(4)` 拿到 `yNzU`,样本值每次跑都不一样 - `mixed(128).length()` 拿到 `128`,单次生成上限就是 128 个字符 - 连跑 500 次 `mixed(10).matches("[2-9A-HJ-NP-Za-hj-kmnp-z]{10}")` 拿到 `true` --- 🔢 **方法序号**:5 🎯 **方法用途**: - 出一道「3 + 5 = ?」式的算术题,题目和正确答案成对返回 - 挡机器人比字符码轻松,加减乘三种题型等概率出 🧩 **方法定义**:`public static ArithmeticCode arithmetic(int maxOperand)` 🗣️ **入参解释**:`public static ArithmeticCode arithmetic(操作数上限)` 📤 **返回值解释**:`ArithmeticCode`,`question` 是题目串,`answer` 是正确答案 💡 **边界口径**: - 减法先交换两个操作数,保证答案不为负 - 操作数默认取自 `0` 到 `maxOperand`,加法按 `(Integer.MAX_VALUE - 1) / 2` 收窄、乘法按 46340 收窄,答案不会溢出 `int` - 题目里的乘号是 `×` 不是 `*`,前端直接展示即可,校验答案别拿题目串去算 - `maxOperand` 小于等于 0 抛 `IllegalArgumentException`,消息带上实际值 🧪 **方法示例**: - `arithmetic(20)` 拿到 `[3 + 17 = ?] 答案 20`,用题目反算与答案一致 - `arithmetic(20)` 也能出 `[20 - 10 = ?] 答案 10`,被减数总在前面 - `arithmetic(20)` 还能出 `[10 × 4 = ?] 答案 40`,乘号是 `×` - 连跑 2000 轮判断 `answer() >= 0` 拿到 `true` - `arithmetic(2_000_000_000)` 拿到 `[25874 × 7766 = ?] 答案 200937484`,乘法操作数被收窄到 46340 以内 - `arithmetic(Integer.MAX_VALUE)` 拿到 `[231234784 - 133571853 = ?] 答案 97662931`,减法不收窄也能算对 - `arithmetic(0)` 抛 `操作数最大值必须大于0,当前为0` - `arithmetic(-5)` 抛 `操作数最大值必须大于0,当前为-5` --- 🔢 **方法序号**:6 🎯 **方法用途**: - 自己装配一道题和它的答案,比如后端已经算好的自定义题型 - 与 `arithmetic` 返回的是同一个记录类型,下游校验逻辑不用分叉 🧩 **方法定义**:`public record ArithmeticCode(String question, int answer)` 🗣️ **入参解释**:`public record ArithmeticCode(题目, 正确答案)` 📤 **返回值解释**:`ArithmeticCode`,题目与答案成对保存 💡 **边界口径**: - 题目为 null 抛 `NullPointerException`,答案不做任何范围校验 - 记录自带 `equals`,同题同答案判等为真,比对时用答案字段而不是拿题目串算 - `question` 原样保存,工具类不会再拼一遍 🧪 **方法示例**: - `new ArithmeticCode("3 + 5 = ?", 8)` 拿到 `question=[3 + 5 = ?],answer=8` - 与字段相同的另一个对象做等值判断,拿到 `true` - `new ArithmeticCode(null, 1)` 抛 `题目不能为null`

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册