From b18f48b652b4b0dc6a8a109316f17a0cf2c75069 Mon Sep 17 00:00:00 2001 From: ZhouXY108 Date: Wed, 4 Jan 2023 13:49:09 +0800 Subject: [PATCH] first commit. --- Markdown-简要手册.md | 622 ++++++++++++++++++ Maven-的相关配置.md | 104 +++ Ubuntu安装MySQL-MariaDB-过程.md | 90 +++ VS-Code-占用-CPU-100.md | 28 + ...运行-Spring-Boot-项目时找不到主类的问题.md | 114 ++++ Vue-侦听对象中的属性.md | 115 ++++ hello-world.md | 43 ++ 使用Maven创建SpringMVC项目.md | 227 +++++++ 前端路由-history-模式刷新-404-的问题.md | 42 ++ 简单JMeter压测.md | 110 ++++ 10 files changed, 1495 insertions(+) create mode 100644 Markdown-简要手册.md create mode 100644 Maven-的相关配置.md create mode 100644 Ubuntu安装MySQL-MariaDB-过程.md create mode 100644 VS-Code-占用-CPU-100.md create mode 100644 VSCode-运行-Spring-Boot-项目时找不到主类的问题.md create mode 100644 Vue-侦听对象中的属性.md create mode 100644 hello-world.md create mode 100644 使用Maven创建SpringMVC项目.md create mode 100644 前端路由-history-模式刷新-404-的问题.md create mode 100644 简单JMeter压测.md diff --git a/Markdown-简要手册.md b/Markdown-简要手册.md new file mode 100644 index 0000000..d103d5b --- /dev/null +++ b/Markdown-简要手册.md @@ -0,0 +1,622 @@ +--- +title: Markdown 简要手册(转载) +date: 2020-03-23 14:02:26 +tags: + - markdown +categories: + - others +--- +## 一、Mrakdown 标题 + +### 1. = 和 - 标记 + +```Markdown +我展示的是一级标题 +================= + +我展示的是二级标题 +----------------- +``` + +### 2. 使用 # 号标记 + +使用 # 号可表示 1-6 级标题,一级标题对应一个 # 号,二级标题对应两个 # 号,以此类推。 +注意 # 与内容之间有一个空行。 + +```Markdown +# 一级标题 +## 二级标题 +### 三级标题 +#### 四级标题 +##### 五级标题 +###### 六级标题 +``` + +--- + +## 二、Markdown 段落 + +### 1. 段落 + +- **文字末尾加两个空格并回车**:表示*段落内*的换行。相当于 html 中的 `
`。 +- **空行**:表示区分开*两个段落*。相当于在 html 中,两段文字分别被 `

` 标签包裹。 + +### 2. 粗体、斜体 + +Markdown 可以使用以下几种字体: + +```Markdown +*斜体文本* +_斜体文本_ + +**粗体文本** +__粗体文本__ + +***粗斜体文本*** +___粗斜体文本___ +``` + +效果: + +> _斜体文本_ +> _斜体文本_ +> **粗体文本** +> **粗体文本** +> **_粗斜体文本_** +> **_粗斜体文本_** + +### 3. 分割线 + +你可以在一行中用三个以上的星号、减号、底线来建立一个分隔线,行内不能有其他东西。你也可以在星号或是减号中间插入空格。下面每种写法都可以建立分隔线: + +```Markdown +*** + +* * * + +***** + +- - - + +---------- +``` + +### 4. 删除线 + +如果段落上的文字要添加删除线,只需要在文字的两端加上两个波浪线 ~~ 即可,实例如下: + +```Markdown +~~BAIDU.COM~~ +``` + +显示效果: + +> ~~BAIDU.COM~~ + +### 5. 下划线 + +下划线可以通过 HTML 的 `` 标签来实现: + +```Markdown +带下划线文本 +``` + +显示效果: + +> ``带下划线文本`` + +### 6. 脚注 + +脚注是对文本的补充说明。 +Markdown 脚注的格式如下: + +```Markdown +[^要注明的文本] +``` + +以下实例演示了脚注的用法: + +```Markdown +创建脚注格式类似这样 [^baidu]。 +[^baidu]: 百度 +``` + +> 创建脚注格式类似这样 [^baidu]。 +> +> [^baidu]: 百度 + +> ~~_VS Code 的预览似乎不支持……_~~ + +--- + +## 三、Markdown 列表 + +### 1. 无序列表 + +无序列表使用星号(\*)、加号(+)或是减号(-)作为列表标记: + +```Markdown +* 第一项 +* 第二项 +* 第三项 + ++ 第一项 ++ 第二项 ++ 第三项 + +- 第一项 +- 第二项 +- 第三项 +``` + +显示结果如下: + +> - 第一项 +> - 第二项 +> - 第三项 +> +> * 第一项 +> * 第二项 +> * 第三项 +> +> - 第一项 +> - 第二项 +> - 第三项 + +### 2. 有序列表 + +有序列表使用数字并加上 . 号来表示,如: + +```Markdown +1. 第一项 +2. 第二项 +3. 第三项 +``` + +显示结果如下: + +> 1. 第一项 +> 2. 第二项 +> 3. 第三项 + +### 3. 列表嵌套 + +列表嵌套只需在子列表中的选项添加四个空格即可: + +```Markdown +1. 第一项: + - 第一项嵌套的第一个元素 + - 第一项嵌套的第二个元素 +2. 第二项: + - 第二项嵌套的第一个元素 + - 第二项嵌套的第二个元素 +``` + +显示结果如下: + +> 1. 第一项: +> - 第一项嵌套的第一个元素 +> - 第一项嵌套的第二个元素 +> 2. 第二项: +> - 第二项嵌套的第一个元素 +> - 第二项嵌套的第二个元素 + +--- + +## 四、Markdown 区块 + +_前面的内容都是以区块展示效果,但这节讲的就是区块,所以效果都不放在区块中。这一节中出现的区块,都是效果本身。_ + +### 1. 区块 + +Markdown 区块引用是在段落开头使用 > 符号 ,然后后面紧跟一个空格符号: + +```Markdown +> 区块引用 +> 百度 +> 学的不仅是技术更是梦想 +``` + +显示结果如下: + +> 区块引用 +> 百度 +> 学的不仅是技术更是梦想 + +### 2. 嵌套区块 + +区块是可以嵌套的,一个 > 符号是最外层,两个 > 符号是第一层嵌套,以此类推: + +```Markdown +> 最外层 +> > 第一层嵌套 +> > > 第二层嵌套 +``` + +> 最外层 +> +>> 第一层嵌套 +>> +>>> 第二层嵌套 +>>> +>> + +### 3. 区块中使用列表 + +区块中使用列表实例如下: + +```Markdown +> 区块中使用列表 +> 1. 第一项 +> 2. 第二项 +> + 第一项 +> + 第二项 +> + 第三项 +``` + +显示结果如下: + +> 区块中使用列表 +> +> 1. 第一项 +> 2. 第二项 +> +> - 第一项 +> - 第二项 +> - 第三项 + +### 4. 列表中使用区块 + +如果要在列表项目内放进区块,那么就需要在 > 前添加四个空格的缩进。 + +```Markdown +区块中使用列表实例如下: + +* 第一项 + > 百度 +* 第二项 +``` + +显示结果如下: + +- 第一项 + > 百度 + > +- 第二项 + +--- + +## 五、Markdown 代码 + +如果是段落上的一个函数或片段的代码可以用反引号把它包起来(`),例如: + +```Markdown +`printf()` 函数 +``` + +显示结果如下: + +> `printf()` 函数 + +### 代码区块 + +将连续的三个 ` 放在代码段的前面和后面,并指定一种语言(也可以不指定)。_本文章中所有的代码都是用这种方式展现的。_ + +> \`\`\`javascript +> \$(document).ready(function () { +> alert('baidu'); +> }); +> \`\`\` + +**_指定语言,某些 Markdown 编辑器可能会给予代码高亮显示。_** + +--- + +## 六、Markdown 链接 + +链接使用方法如下: + +```Markdown +[链接名称](链接地址) + +或者 + +<链接地址> +``` + +实例: + +```Markdown +这是一个链接 [百度](https://www.baidu.com) +``` + +显示结果如下: + +> 这是一个链接 [百度](https://www.baidu.com) + +直接使用链接地址: + +```Markdown + +``` + +显示结果如下: + +> [https://www.baidu.com](https://www.baidu.com) + +### 高级链接 + +我们可以通过变量来设置一个链接,变量赋值在文档末尾进行: + +```Markdown +这个链接用 1 作为网址变量 [Google][1] +这个链接用 baidu 作为网址变量 [Baidu][baidu] +然后在文档的结尾为变量赋值(网址) + + [1]: http://www.google.com/ + [baidu]: http://www.baidu.com/ +``` + +效果如下: + +> 这个链接用 1 作为网址变量 [Google][1] +> 这个链接用 baidu 作为网址变量 [Baidu][baidu] +> 然后在文档的结尾为变量赋值(网址) +> +> [1]: http://www.google.com/ +> [baidu]: http://www.baidu.com/ + +--- + +## 七、Markdown 图片 + +Markdown 图片语法格式如下: + +```Markdown +![alt 属性文本](图片地址) + +![alt 属性文本](图片地址 "可选标题") +``` + +- 开头一个感叹号 ! +- 接着一个方括号,里面放上图片的替代文字 +- 接着一个普通括号,里面放上图片的网址,最后还可以用引号包住并加上选择性的 'title' 属性的文字。 + +实例: + +```Markdown +![BAIDU 图标](http://...) + +![BAIDU 图标](http://... "BAIDU") +``` + +当然,你也可以像网址那样对图片网址使用变量: + +```Markdown +这个链接用 1 作为网址变量 [百度][1]. +然后在文档的结尾为变量赋值(网址) + +[1]: http://... +``` + +--- + +## 八、Markdown 表格 + +Markdown 制作表格使用 | 来分隔不同的单元格,使用 - 来分隔表头和其他行。 + +语法格式如下: + +```Markdown +| 表头 | 表头 | +| ------ | ------ | +| 单元格 | 单元格 | +| 单元格 | 单元格 | +``` + +以上代码显示结果如下: + +> | 表头 | 表头 | +> | ------ | ------ | +> | 单元格 | 单元格 | +> | 单元格 | 单元格 | + +### 对齐方式 + +我们可以设置表格的对齐方式: + +- -: 设置内容和标题栏居右对齐。 +- :- 设置内容和标题栏居左对齐。 +- :-: 设置内容和标题栏居中对齐。 + +实例如下: + +```Markdown +| 左对齐齐齐齐 | 右对齐齐齐齐 | 居中对齐齐齐齐 | +| :----------- | -----------: | :------------: | +| 单元格 | 单元格 | 单元格 | +| 单元格 | 单元格 | 单元格 | +``` + +以上代码显示结果如下: + +> | 左对齐齐齐齐 | 右对齐齐齐齐 | 居中对齐齐齐齐 | +> | :----------- | -----------: | :------------: | +> | 单元格 | 单元格 | 单元格 | +> | 单元格 | 单元格 | 单元格 | + +--- + +## 九、Markdown 高级技巧 + +### 支持的 HTML 元素 + +不在 Markdown 涵盖范围之内的标签,都可以直接在文档里面用 HTML 撰写。 + +目前支持的 HTML 元素有:`` `` `` `` `` `` `
` 等 ,如: + +```Markdown +使用 Ctrl+Alt+Del 重启电脑 +``` + +输出结果为: + +> 使用 ``Ctrl``+``Alt``+``Del`` 重启电脑 + +### 转义 + +Markdown 使用了很多特殊符号来表示特定的意义,如果需要显示特定的符号则需要使用转义字符,Markdown 使用反斜杠转义特殊字符: + +```Markdown +**文本加粗** +\*\* 正常显示星号 \*\* +``` + +输出结果为: + +> **文本加粗** +> \*\* 正常显示星号 \*\* + +Markdown 支持以下这些符号前面加上反斜杠来帮助插入普通的符号: + +```Markdown +\ 反斜线 +` 反引号 +* 星号 +_ 下划线 +{} 花括号 +[] 方括号 +() 小括号 +# 井字号 ++ 加号 +- 减号 +. 英文句点 +! 感叹号 +``` + +### 公式 + +当你需要在编辑器中插入数学公式时,可以使用两个美元符 \$\$ 包裹 TeX 或 LaTeX 格式的数学公式来实现。提交后,问答和文章页会根据需要加载 Mathjax 对数学公式进行渲染。 + +--- + +## 十、其它 + +typora 还支持以下流程图、时序图(顺序图)、甘特图 + +### 横向流程图: + +```mermaid +graph LR +A[方形] -->B(圆角) + B --> C{条件a} + C -->|a=1| D[结果1] + C -->|a=2| E[结果2] + F[横向流程图] +``` + +### 竖向流程图: + +```mermaid +graph TD +A[方形] --> B(圆角) + B --> C{条件a} + C --> |a=1| D[结果1] + C --> |a=2| E[结果2] + F[竖向流程图] +``` + +### 标准流程图: + +```flow +st=>start: 开始框 +op=>operation: 处理框 +cond=>condition: 判断框(是或否?) +sub1=>subroutine: 子流程 +io=>inputoutput: 输入输出框 +e=>end: 结束框 +st->op->cond +cond(yes)->io->e +cond(no)->sub1(right)->op +``` + +### 标准流程图(横向): + +```flow +st=>start: 开始框 +op=>operation: 处理框 +cond=>condition: 判断框(是或否?) +sub1=>subroutine: 子流程 +io=>inputoutput: 输入输出框 +e=>end: 结束框 +st(right)->op(right)->cond +cond(yes)->io(bottom)->e +cond(no)->sub1(right)->op +``` + +### UML 时序图: + +```sequence +对象A->对象B: 对象B你好吗?(请求) +Note right of 对象B: 对象B的描述 +Note left of 对象A: 对象A的描述(提示) +对象B-->对象A: 我很好(响应) +对象A->对象B: 你真的好吗? +``` + +### UML 时序图: + +```sequence +Title: 标题:复杂使用 +对象A->对象B: 对象B你好吗?(请求) +Note right of 对象B: 对象B的描述 +Note left of 对象A: 对象A的描述(提示) +对象B-->对象A: 我很好(响应) +对象B->小三: 你好吗 +小三-->>对象A: 对象B找我了 +对象A->对象B: 你真的好吗? +Note over 小三,对象B: 我们是朋友 +participant C +Note right of C: 没人陪我玩 +``` + +### UML 标准时序图: + +```mermaid +%% 时序图例子,-> 直线,-->虚线,->>实线箭头 + sequenceDiagram + participant 张三 + participant 李四 + 张三->王五: 王五你好吗? + loop 健康检查 + 王五->王五: 与疾病战斗 + end + Note right of 王五: 合理 食物
看医生... + 李四-->>张三: 很好! + 王五->李四: 你怎么样? + 李四-->王五: 很好! +``` + +### 甘特图: + +```mermaid +%% 语法示例 + gantt + dateFormat YYYY-MM-DD + title 软件开发甘特图 + section 设计 + 需求 :done, des1, 2014-01-06,2014-01-08 + 原型 :active, des2, 2014-01-09, 3d + UI设计 : des3, after des2, 5d + 未来任务 : des4, after des3, 5d + section 开发 + 学习准备理解需求 :crit, done, 2014-01-06,24h + 设计框架 :crit, done, after des2, 2d + 开发 :crit, active, 3d + 未来任务 :crit, 5d + 耍 :2d + section 测试 + 功能测试 :active, a1, after des3, 3d + 压力测试 :after a1 , 20h + 测试报告 : 48h +``` diff --git a/Maven-的相关配置.md b/Maven-的相关配置.md new file mode 100644 index 0000000..1801aa3 --- /dev/null +++ b/Maven-的相关配置.md @@ -0,0 +1,104 @@ +--- +title: Maven 的相关配置 +date: 2020-09-29 20:51:38 +tags: + - 开发工具 + - Maven +categories: + - 开发工具 +--- +> Apache Maven,是一个软件(特别是 Java 软件)项目管理及自动构建工具,由 Apache 软件基金会所提供。基于项目对象模型(缩写:POM)概念,Maven 利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。 +> +> Maven 也可被用于构建和管理各种项目,例如 C#,Ruby,Scala 和其他语言编写的项目。Maven 曾是 Jakarta 项目的子项目,现为由 Apache 软件基金会主持的独立 Apache 项目。 +> +>

——《维基百科》

+ +由于众所周知的原因,Maven 下载东西的时候总会特别慢,直到失败。下面列出几个常见配置: + +## 一、将 archetypeCatalog 参数设为 internal + +在 maven 的 VM Options 加上 -DarchetypeCatalog=internal 参数。 + +- IntelliJ IDEA : 设置中的 **Build, Execution, Deployment** -> **Build Tools** -> **Maven** -> **Runner** 的 VM Options 中输入 `-DarchetypeCatalog=internal`。 +- VS Code : 设置中的 **扩展** -> **Maven for Java** -> Maven > Executable: **Options** 中输入 `-DarchetypeCatalog=internal`。 + +--- + +## 二、配置阿里云镜像 + +### 1. 为单个项目配置阿里云镜像 + +我们可以在项目的 pom.xml 文件的 project 节点中为该项目单独配置阿里云镜像,如下所示: + +```xml + + ... + + + aliyun + https://maven.aliyun.com/repository/public + + true + + + false + + + + + + aliyun-plugin + https://maven.aliyun.com/repository/public + + true + + + false + + + + ... + +``` + +这样,当我们从 git 上拉取项目之后,就可以直接使用阿里云的镜像。 + +> 注意:别忘了 pluginRepositories 节点的配置。网上不少文章只介绍了 repositories 的配置,但是这样可能会出现依赖包从阿里云下载,而 Maven 插件依旧从 repo.maven.apache.org 下载的情况,最终下载缓慢甚至报错。 + +### 2. 修改 Maven 的配置文件 + +我们还可以修改 Maven 安装目录下 `conf` 文件夹中的 `settings.xml` 文件,找到其中的 `mirrors` 节点,在其中添加如下配置: + +```xml + + alimaven + *,!jeecg,!jeecg-snapshots + aliyun maven + https://maven.aliyun.com/nexus/content/groups/public/ + +``` + +> 一些软件默认会去使用 `${用户文件夹}/.m2/settings.xml` 配置文件,我们可以手动指定 settings.xml 文件的路径。我个人的做法是干脆将修改后的 `settings.xml` 拷贝一份到 .m2 文件夹中,这样不管哪个软件从哪里加载配置文件,都是一样的内容。 + +--- + +## 三、本地仓库 + +Maven 默认的本地仓库位于 `个人文件夹\.m2\repository`,比如 `C:\Users\zhouxy\.m2\repository`、`~\.m2\repository`,这个我一般就不去修改了。总之下载过的依赖都会放在这里,而每次创建、打开项目,Maven 都会先从这里寻找依赖。你也可以在 settings.xml 中修改这个路径。 + +在 `settings` 的开始标签下面就有被注释的内容说明如何配置,也就是在 `settings` 节点中添加如下代码: + +```xml +D:/ZhouXY/.m2/repository +``` + +这样 maven 就会把 `D:/ZhouXY/.m2/repository` 这个目录当成本地仓库,你可以替换成你自己的文件夹。 + +## 随便说点什么 + +好久没更新博客了,最近在学 Spring,由于有点赶时间,所以笔记没有整理得很整齐,示例程序也零零散散,等有时间整理好了,再一并发布吧。 + +另外,博客换了个主题,有些东西还没配置好,就先这样将就吧。 diff --git a/Ubuntu安装MySQL-MariaDB-过程.md b/Ubuntu安装MySQL-MariaDB-过程.md new file mode 100644 index 0000000..4e3dc26 --- /dev/null +++ b/Ubuntu安装MySQL-MariaDB-过程.md @@ -0,0 +1,90 @@ +--- +title: Ubuntu 安装MySQL(MariaDB)过程 +date: 2020-07-22 22:54:29 +tags: + - Linux + - Ubuntu + - MySQL + - MariaDB + - 数据库 +categories: + - MariaDB +--- + +> 本文内容简单,只是整理了一下常规操作而已。 + +> MariaDB 是 MySQL 的一个分支主要由开源社区在维护,采用 GPL 授权许可。开发这个分支的原因之一是:甲骨文公司收购 MySQL 后,有将 MySQL 闭源的潜在风险,因此社区采用分支的方式来避开这个风险。 +> +> MariaDB 的目的是完全兼容 MySQL,包括 API 和命令行,使之能轻松成为 MySQL 的代替品。 + +> 一般情况下我在个人的学习和开发中都会使用 MariaDB 来代替 MySQL,就像我会使用 Open JDK 来代替 Oracle JDK 一样。 + +## 1. 安装 + +在 Ubuntu 上安装 MySQL: +``` +sudo apt-get install mysql-client mysql-server +``` + +安装 MariaDB 的话,把 "mysql" 改成 "mariadb" 即可: +``` +sudo apt-get install mariadb-client mariadb-server +``` + +一般来说安装完成之后都是自动运行的,如果没有运行,可以执行 `sudo service mysql start` 启动它(MySQL 和 MariaDB 都一样)。 + +> 关闭服务:`sudo service mysql stop` +> 查看服务状态:`sudo service mysql status` + +> 我在阿里云的 Ubuntu 20.04 上安装 MySQL,版本输出信息为: +> Server version: 8.0.20-0ubuntu0.20.04.1 (Ubuntu) +> +> 在本地机的 Ubuntu 18.04.4 MariaDB,版本输出信息为: +> Server version: 10.1.44-MariaDB-0ubuntu0.18.04.1 18.04 + +## 2. 初始化 + +``` +mysqld -initialize +``` +耐心等待命令执行完成。 + +## 3. 设置 + +### 3.1 登录数据库 +切换系统 root 用户,输入 +``` +mysql -u root -p +``` +不用输入密码,直接回车,登录 MariaDB(或者 MySQL)。 + +### 3.2 修改密码 +``` +set password for root@localhost = password('123'); +``` +> 否则默认密码为空。 + +### 3.3 修改 `plugin` 属性为 `mysql_native_password` +```sql +use mysql; +update user set plugin='mysql_native_password' where user='root'; +``` +然后输入 `flush privileges;` 使之生效。 + +> 否则系统的其他用户无法登录数据库的 root 用户。 +> ERROR 1698 (28000): Access denied for user 'root'@'localhost' + +### 3.4 将 `host` 属性设置为 `%` +```sql +use mysql; +update user set host = '%' where user = 'root'; +``` +然后输入 `flush privileges;` 使之生效。 +> 否则其它设备上的客户端(DataGrid、Netcat 以及我们自己编写的程序等)无法登录数据库的 root 用户。 + +## 4. 注意!!! +上面的 3.3、3.4 针对的是我学习生活中需要在其他设备、其他系统用户上登录数据库的 root 用户。实际上,为了安全,我们可能不会允许这么做。 + +例如我们可能保留 root 用户的 plugin 属性为 unix_socket,系统的普通用户也只能登录数据库的其他用户,只有系统的 root 用户才能登录数据库的 root 用户。 + +我们还可能保留 root 用户的 host 属性为 localhost,或者只允许在指定的主机上登录 root,还可以添加另一个数据库用户(设置好适合的权限),用来在其他设备上登录并操作数据库。 \ No newline at end of file diff --git a/VS-Code-占用-CPU-100.md b/VS-Code-占用-CPU-100.md new file mode 100644 index 0000000..8976709 --- /dev/null +++ b/VS-Code-占用-CPU-100.md @@ -0,0 +1,28 @@ +--- +title: VS Code 占用 CPU 100% +date: 2020-03-25 10:03:26 +tags: + - VS Code + - 开发工具 +categories: + - 开发工具 +--- + +VS Code 作为 Microsoft 开发的代码编辑器,免费、开源、跨平台,而且颜值高,关键是插件丰富,支持多种语言、IntelliSense 智能感知、强大的调试功能、内置 git 操作等等,让我对这款软件爱不释手,在这里跟网友安利一波。 + +VS Code 平时我用着也没什么问题,~~(可能是因为我平时项目小),~~不过最近需要用 Vue 写前端,使用 Vue CLI 新建了一个项目: +``` +vue init webpack my-project +``` +然后用 VS Code 打开,这下子不得了,电脑的 CPU 占用率居然到了 100%,风扇“转呀转呀转不停”,整个电脑变得特别卡。艰难地打开了任务管理器,在 VS Code 下看到了两个 `rg.exe` 的进程,CPU 基本上都是被它占满的。上网找了下,早在 2018 年就有人遇到了这个问题,~~话说这都 2020 年了,~~**解决方法是在设置里将 `Search: Follow Symlinks` 关掉**。 + +```json +"search.followSymlinks": false +``` + + + +> 相关链接: +> Visual Studio Code 官网: +> Vue.js 官网: + diff --git a/VSCode-运行-Spring-Boot-项目时找不到主类的问题.md b/VSCode-运行-Spring-Boot-项目时找不到主类的问题.md new file mode 100644 index 0000000..5a433ac --- /dev/null +++ b/VSCode-运行-Spring-Boot-项目时找不到主类的问题.md @@ -0,0 +1,114 @@ +--- +title: VSCode 运行 Spring Boot 项目时找不到主类的问题 +date: 2020-12-09 16:42:30 +tags: + - VS Code + - Spring + - Spring Boot +categories: + - Spring Boot +--- + +## 开发环境 + +VSCode 众多的插件极大地扩展了它的功能,使得它可以做很多开发,如 C/C++、Java、Python、Vue 等。有时候,我会拿它来做 Spring Boot 的开发。 + +我安装的插件有: +- [Spring Boot Extension Pack](https://marketplace.visualstudio.com/items?itemName=Pivotal.vscode-boot-dev-pack) +- [Java Extension Pack](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-pack) + +> 这两个扩展包中包含了必要的插件。 + +> 本文默认你已经安装配置好了 JDK 和 maven。 + +## 问题描述 + +当我们执行了 maven 的 clean 操作之后,点击 `main` 函数上面的 `run` 视图运行项目时,会出现“找不到主类”的问题,如下所示: +``` +错误: 找不到或无法加载主类 xyz.zhouxy.demo.DemoApplication +原因: java.lang.ClassNotFoundException: xyz.zhouxy.demo.DemoApplication +``` + +## 问题分析 + +这是因为,当我们执行 clean 之后,target 文件夹被删除了,也就是编译后的 class 文件都被删掉了,所以当我们点击 run 试图运行项目时,Java 找不到主类。 + +### 为什么 IDEA 不会出现这种问题? + +IDEA 默认在运行项目之前,有一个 build 的过程。我们打开“运行/调试配置”窗口可以看到,在“执行前”列表中有一个“构建”,如果我们按下方的减号(-)把它去掉,并执行 `mvn clean`,点击“运行”或者“调试”按钮的话,也会同样“找不到主类”。 + +## 解决方法 + +我们可以在运行项目前,先执行 `mvn compile` 命令,或者打开 pom.xml 文件,然后右键,点击“Update Project”,完成对项目的编译。 + +## 配置 + +每次运行项目之前都得先执行编译命令,这样的开发体验并不好,我们可以通过 VSCode 的一些配置来解决。 + +### 1. 配置 launch.json + +如果你安装前面所说装好了插件,那么在左侧的资源管理器面板中,应该会出现一个 **SPRING-BOOT DASHBOARD** 面板,上面列出了当前 Spring Boot 项目的名称,在改项目名称上右键,点击“start”。 + +这时候,如果你的项目已经编译好的话,则可以在下方的“调试控制台”看到输出;如果你执行了 `mvn clean` 的话,也可以在“调试控制台”看到讨厌的“找不到主类”。 + +实际上,你会发现在项目中多了一个 `.vscode` 文件夹,里面有一个 `launch.json` 文件,内容类似于下面这样: +```JSON +{ + "configurations": [ + { + "type": "java", + "name": "Spring Boot-DemoApplication", + "request": "launch", + "cwd": "${workspaceFolder}", + "console": "internalConsole", + "mainClass": "xyz.zhouxy.demo.DemoApplication", + "projectName": "demo", + "args": "" + } + ] +} +``` +其中,mainClass 和 projectName 的值会与这里的不同,是插件根据你的项目生成的,不用改。我们要做的是,在 `args` 后面再添加一个 `preLaunchTask` 属性,值为 `"build"`: +```JSON +{ + "configurations": [ + { + "type": "java", + "name": "Spring Boot-DemoApplication", + "request": "launch", + "cwd": "${workspaceFolder}", + "console": "internalConsole", + "mainClass": "xyz.zhouxy.demo.DemoApplication", + "projectName": "demo", + "args": "", + "preLaunchTask": "build" + } + ] +} +``` +也就是说,我们希望在运行/调试这个项目之前,都执行一遍 `build` 这个任务。`build` 的具体内容,则是在 tasks.json 中配置的。 + +### 2. 配置 tasks.json + +在 `.vscode` 文件夹中,新建一个名为 `tasks.json` 的文件,内容如下: +```JSON +{ + "version": "2.0.0", + "options": { + "cwd": "${workspaceRoot}" + }, + "tasks": [ + { + "label": "build", + "type": "shell", + "command": "mvn clean compile" + } + ] +} +``` + +我们在其中配置了一个名为 `build` 的任务,让它在 shell 中执行 `mvn clean compile` 命令,这样在每次运行/调试项目之前,都会在“**终端**”中执行一次 `mvn clean compile` 命令,而 Spring Boot 的输出,会在“调试控制台”显示。 + +> 其实,launch.json 中的 `console` 属性的值,我们可以配置为 `integratedTerminal`,这样 Spring Boot 的输出也会在终端中显示,但我还是建议 `console` 的值保持为 `internalConsole`,因为它可以设置筛选器,过滤出需要的输出。 + +现在,不论你 **点击主函数上的 run 或者 debug**、**在运行面板中点击运行按钮**,还是**在 SPRING-BOOT DASHBOARD 面板中点击运行项目**,都会调用 maven 进行编译,然后再运行。 \ No newline at end of file diff --git a/Vue-侦听对象中的属性.md b/Vue-侦听对象中的属性.md new file mode 100644 index 0000000..11dfae5 --- /dev/null +++ b/Vue-侦听对象中的属性.md @@ -0,0 +1,115 @@ +--- +title: Vue 侦听对象中的属性 +date: 2021-05-08 17:52:33 +tags: + - 前端 + - Vue +categories: + - 前端 +--- + +Vue 提供了一个 watch 方法可以让使用者去监听某些 data 内的数据变动,触发相应的方法,比如: + +```javascript +export default { + data() { + return { + question: '', + answer: 'Questions usually contain a question mark. ;-)' + } + }, + watch: { + // whenever question changes, this function will run + question(newQuestion, oldQuestion) { + if (newQuestion.indexOf('?') > -1) { + this.getAnswer() + } + } + }, + methods: { + getAnswer() { + this.answer = 'Thinking...' + axios + .get('https://yesno.wtf/api') + .then(response => { + this.answer = response.data.answer + }) + .catch(error => { + this.answer = 'Error! Could not reach the API. ' + error + }) + } + } +} +``` + +但是,当我们要侦听的数据是某个对象中的属性怎么办? + +以前几天我所遇到的需求为例,一个对话框中的表单绑定了 `queryData`,其中 `date` 绑定了一个日期选择器,`count` 则绑定了一个计数器,`max` 则是该计数器的值,需要根据 `date` 的值发送请求动态获取: + +```javascript +export default { + data() { + return { + max: 0, + queryData: { + date: '2021-05-08', + count: 0, + // 其它属性... + } + } + }, + // ... + methods: { + getMax(date) { + // 发送请求后根据响应的值修改 this.max 的值 + } + } +} +``` + +这时,我们如果只侦听 `queryData`,`queryData.date` 更改时并不会触发侦听器,因为我们并没有给 `queryData` 重新赋值。 + +很多人都表示可以设置侦听器的 `deep` 选项为 `true`,说实话,如果只是侦听 `date` 属性的话,我并不推荐这种方法,因为这样不仅 `date` 属性更改时会执行侦听器中的方法,其它属性(比如 `count`)的值改变了,也会执行侦听器中的方法,还需要在其中加入判断,就很不理想。我推荐的方式是,将**计算属性**和**监听器**结合起来使用,如下: + +```javascript +export default { + data() { + return { + max: 0, + queryData: { + date: '2021-05-08', + count: 0, + // 其它属性... + } + } + }, + computed: { + _queryData_date() { + return this.queryData.date + } + }, + watch: { + _queryData_date(oldDate, newDate) { + this.getMax(newDate) + } + }, + methods: { + getMax(date) { + // 发送请求后根据响应的值修改 this.max 的值 + } + } +} +``` + +这样,我们就只侦听了 `queryData.date` 的值,可以在它改变时执行 `getMax` 方法。 + +> 关于计算属性和侦听器的使用方法,请查看 Vue 的官方文档: +> +> - Vue 2.x +> https://cn.vuejs.org/v2/guide/computed.html +> https://cn.vuejs.org/v2/guide/reactivity.html +> - Vue 3.x +> https://v3.cn.vuejs.org/guide/computed.html +> https://v3.cn.vuejs.org/guide/reactivity-computed-watchers.html +> +> ***其实使用组合式 API的话,2.x 和 3.x 在这里并没有什么区别;Vue 3.x 中在 setup 里面使用的话,思路也是一样,只是形式不同。*** diff --git a/hello-world.md b/hello-world.md new file mode 100644 index 0000000..0642f47 --- /dev/null +++ b/hello-world.md @@ -0,0 +1,43 @@ +--- +title: Hello World +date: 2020-03-18 16:05:50 +categories: + - others +--- +[Hexo](https://hexo.io/) 自带的一篇文章,里面介绍了 Hexo 的几个常用的命令。第一篇文章我就保留它的内容,以便日后使用时作为参考。同时以此为纪念。 + +
ZhouXY
+ +## 快点开始吧 + +### 新建文章 + +``` bash +$ hexo new "My New Post" +``` + +查看更多: [Writing](https://hexo.io/docs/writing.html) + +### 启动服务器 + +``` bash +$ hexo server +``` + +查看更多: [Server](https://hexo.io/docs/server.html) + +### 生成静态文件 + +``` bash +$ hexo generate +``` + +查看更多: [Generating](https://hexo.io/docs/generating.html) + +### 部署到远程站点 + +``` bash +$ hexo deploy +``` + +查看更多: [Deployment](https://hexo.io/docs/one-command-deployment.html) diff --git a/使用Maven创建SpringMVC项目.md b/使用Maven创建SpringMVC项目.md new file mode 100644 index 0000000..c8357e8 --- /dev/null +++ b/使用Maven创建SpringMVC项目.md @@ -0,0 +1,227 @@ +--- +title: 使用 Maven 创建 Spring MVC 项目 +date: 2020-11-11 15:52:52 +tags: + - Spring + - Spring MVC + - Maven +categories: + - Spring +--- +> Maven 可以用来创建 Java 项目,并管理依赖,创建出来的项目不依赖于特定的 IDE,可以用 Eclipse、IDEA 社区版、IDEA 旗舰版,甚至 VSCode 来开发。_(具体 VSCode 怎么配置 Java 开发环境,这里不再赘述)_ + +> Maven 创建项目时,需要从国外的服务器上下载项目的依赖、插件等,速度会很慢,甚至导致创建项目失败,具体如何配置,请参考我的另一篇博客 [Maven 的相关配置](http://zhouxy.xyz/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Maven-%E7%9A%84%E7%9B%B8%E5%85%B3%E9%85%8D%E7%BD%AE/)。 + +## 一、创建 Java Web 项目 + +### 1. 使用 maven 创建 Java Web 项目 + +启动开发环境,用 Maven 创建项目,从原型中选择“maven-archetype-webapp”,再依次指定 groupId、artifactId 等信息,不同的 IDE 创建 Maven 项目的过程略有不同,但大同小异。 + +### 2. 完善目录结构 + +在 `main` 文件夹中创建 `java` 和 `resources` 两个文件夹;在 `src` 文件夹中创建 `test` 文件夹,并中其中也创建 `java` 和 `resources` 两个文件夹。 + +- ${basedir}/src/main/java 文件夹中创建 Java 包和类; +- ${basedir}/src/main/resources 文件夹中存放静态文件; +- ${basedir}/src/test/java 文件夹中创建项目的测试类,比如说 Junit 代码; +- ${basedir}/src/test/resources 存放测试用的资源。 + +> 在 IDEA 中新建目录时,会有几个提示,因为 IDEA 通过 pom.xml 文件知道这是个 maven 项目,猜测并帮助你创建标准的 maven 项目骨架。这时候按住 shift 键,并按住下方向键,可将其全部选中,再按回车,即可一次性创建好所有文件夹并标记好,这样就不用一个一个创建并标记了。在 VSCode 中,并不会对项目中的文件夹进行标记(VSCode 的一些图标可能会根据文件名进行猜测),所以一个一个创建文件夹就完事了。 + +初始的项目路径如下: +![初始项目结构](http://zhouxy.xyz/img/163635_48fc6498_6543055.png) +我们需要完善其目录结构: +![完善后的目录结构](http://zhouxy.xyz/img/164009_81ccdf56_6543055.png) + +### 3. 添加 Servlet 和 JSP 的依赖包 +在 pom.xml 文件中的 `dependencies` 标签中添加 Servlet 和 JSP 的依赖: +```xml + + + javax.servlet + javax.servlet-api + 4.0.1 + + + + + javax.servlet.jsp + javax.servlet.jsp-api + 2.3.3 + + + jstl + jstl + 1.2 + +``` +这样,一个 Java Web 项目就创建好了。 + + +## 二、配置 Spring MVC + +### 1. 导入 Spring、Spring MVC 的依赖 + +在 pom.xml 文件中的 `dependencies` 标签中添加如下依赖: +```xml + + org.springframework + spring-webmvc + 5.2.8.RELEASE + +``` +> 导入 spring-webmvc 好像就会自动导入 spring-aop、spring-beans、spring-context、spring-core、spring-expression、spring-web 这些个依赖。 + +### 2. 配置并启用 Spring MVC + +以前(包括现在很多人)配置 Spring MVC 都是通过 web.xml 配置的,随着 Java 和 Spring 的发展,现在完全可以不使用 xml 配置并启用 Spring MVC。 + +下面的配置适用于 Spring 3.2 及以上版本(我写本文时,Spring 的版本已经是 5.2.9 了),且 Servlet 容器支持 Servlet 3.0(2009 年 12 月发布)。所以,你的开发环境大概率支持以下配置方法。 + +#### 2.1.1 创建 RootConfig 配置类 + +**RootConfig 类将用于非 web 部分的配置。** *本示例中重在与 Web 相关的配置,所以 `RootConfig` 相对简单,实际项目中将会有很多非 Web 的配置来充实完善 RootConfig。* + +```java +package xyz.zhouxy.chapter01.config; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.context.annotation.ComponentScan.Filter; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +@Configuration +@ComponentScan(basePackages = "xyz.zhouxy.chapter01", + excludeFilters = { + @Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class)}) +public class RootConfig { +} +``` + +#### 2.1.2 创建 WebConfig 配置类 + +WebConfig 将用于 DispatcherServlet 应用程序上下文配置。 + +```java +package xyz.zhouxy.chapter01.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.view.InternalResourceViewResolver; + +@Configuration +@EnableWebMvc +@ComponentScan("xyz.zhouxy.chapter01.web") +public class WebConfig implements WebMvcConfigurer { + + @Bean + public ViewResolver viewResolver() { + InternalResourceViewResolver resolver = new InternalResourceViewResolver(); + resolver.setPrefix("/WEB-INF/views/"); + resolver.setSuffix(".jsp"); + resolver.setExposeContextBeansAsAttributes(true); + return resolver; + } + + @Override + public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + } +} +``` +- `@EnableWebMvc` 注解启动 Spring MVC; +- `@ComponentScan` 启用组件扫描;所指定的包中的所有带有 `@Controller` 注解的类都会成为 Spring bean。 +- `viewResolver` 方法配置 JSP 视图解析器,将 `InternalResourceViewResolver` 类的实例声明为 bean; +- 重写的 `configureDefaultServletHandling` 方法,通过调用 `DefaultServletHandlerConfigurer` 的 `enable()`,要求 `DispatcherServlet` 将对静态资源的请求转发到 Servlet 容器中默认的 Servlet 上,而不是使用 `DispatcherServlet` 本身来处理此类请求。 + + +> 《Spring 实战(第4版)》中,WebConfig 是继承自 `WebMvcConfigurerAdapter` 类,但当前的版本,该类已经过时,`WebConfig` 类实现 `WebMvcConfigurer` 接口即可。 + +#### 2.1.3 创建 WebAppInitializer 类 + +当我们创建了 `RootConfig` 和 `WebConfig` 配置类之后,怎么让它们应用于我们的项目呢?答案是通过写一个 `WebAppInitializer`。 + +`WebAppInitializer` 类继承自 `AbstractAnnotationConfigDispatcherServletInitializer`,所以它会自动地配置 `DispatcherServlet` 和 Spring 应用上下文,Spring 应用上下文会位于应用程序的 Servlet 上下文中。 + +```java +package xyz.zhouxy.chapter01.config; + +import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; + +public class WebAppInitializer + extends AbstractAnnotationConfigDispatcherServletInitializer { + + @Override + protected Class[] getRootConfigClasses() { + return new Class[]{ RootConfig.class }; + } + + @Override + protected Class[] getServletConfigClasses() { + return new Class[]{ WebConfig.class }; + } + + @Override + protected String[] getServletMappings() { + return new String[] { "/" }; + } +} +``` + +> **更多细节:** +> 在 Servlet 3.0 环境中,容器会在类路径中查找 `javax.servlet.ServletContainerInitializer` 接口的实现类,找到的话,就用它来配置 Servlet 容器。Spring 的 `SpringServletContainerInitializer` 类即为该接口的实现类,`SpringServletContainerInitializer` 又会查找实现 `WebApplicationInitializer` 的类并将配置的任务交给它们来完成。 +> +> Spring 3.2 中引入了一个便利的 `WebApplicationInitializer` 基础实现,也就是 `AbstractAnnotationConfigDispatcherServletInitializer`。 +> +> 因为我们的 `WebAppInitializer` 继承自 `AbstractAnnotationConfigDispatcherServletInitializer`(同时也就实现了 `WebApplicationInitializer` 接口),因此当部署到 Servlet 3.0 容器中的时候,容器会自动发现它,并用它来配置 Servlet 上下文。 + + +## 三、使用 Spring MVC + +前面我们已经配置好了 Spring MVC,接下来我们编写一个 Controller 来测试一下吧。 + +### 1. 创建页面 +在 ${basedir}/src/main/webapp/WEB-INF/ 文件夹中新建一个 `views` 文件夹,再在 `views` 文件夹中新建 `test.jsp` 文件: +```html +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + +Test + + +

Test Page

+ + +``` +### 2. 创建 TestController +```java +package xyz.zhouxy.chapter01.web; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class TestController { + + @GetMapping("/test") + public String toTestPage() { + return "test"; + } +} +``` +### 3. 部署项目 +将项目部署到 Tomcat,应用上下文为 `chapter01`。 +> 不同 IDE 配置 Tomcat 部署项目具体细节找时间再写吧。 + +在浏览器输入 http://localhost:8080/chapter01/test ,由于上面的映射,`toTestPage()` 方法将被执行,它返回字符串“test”,被视作视图的名称,由 `WebConfig` 类中配置的视图解析器解析为具体的视图 `/WEB-INF/views/test.jsp`。 +![运行结果](http://zhouxy.xyz/img/233117_0a37d814_6543055.png "屏幕截图.png") \ No newline at end of file diff --git a/前端路由-history-模式刷新-404-的问题.md b/前端路由-history-模式刷新-404-的问题.md new file mode 100644 index 0000000..266a35d --- /dev/null +++ b/前端路由-history-模式刷新-404-的问题.md @@ -0,0 +1,42 @@ +--- +title: 前端路由 history 模式刷新 404 的问题 +date: 2020-04-13 18:05:23 +tags: + - 前端 + - 前端路由 +categories: + - 前端 +--- + +> 能在官方文档中找到答案的问题,都是我们自己没认真看文档的问题。 +>

——ZhouXY

+ +前段时间由于要做一个东西而接触了 Vue,这两天因为某些需要又开始接触 Angular,有那么一点点点点点的 Vue 的知识,看 Angular 的基础其实不算太吃力。 + +## 问题描述 +今天学习的过程中用到了路由,在开发环境中执行 `ng serve`,然后在浏览器上访问 `http://localhost:4200/test`,跑起来一切正常,但当我执行 `ng build` 进行构建并把它部署到 Nginx 中的时候就出事了。像 `http://example.com/test` 这种***深链接***,一刷新就 `404`。 + +上网找了一圈,几乎所有的博客、文章教程都是教怎么把路由改成 hash 模式的。我就纳闷了,路由提供了 history 模式,就用都不能用了?~~重点是,我真心觉得带`#`的地址好难看!~~ 在网上找了半天才反应过来我居然把最重要的官方文档给忘了……~~被自己蠢哭了 T^T~~ + +## 怎么解决 +官方文档讲的很清楚: +> ### 带路由的应用必须以 index.html 作为后备页面 +> Angular 应用很适合用简单的静态 HTML 服务器提供服务。 你不需要服务端引擎来动态合成应用页面,因为 Angular 会在客户端完成这件事。 +> +> 如果该应用使用 Angular 路由器,你就必须配置服务器,让它对不存在的文件返回应用的宿主页(index.html)。 +> +> 带路由的应用应该支持“深链接”。 所谓深链接就是指一个 URL,它用于指定到应用内某个组件的路径。 比如,http://www.mysite.com/heroes/42 就是一个到英雄详情页面的深链接,用于显示 id: 42 的英雄。 +> +> 当用户从运行中的客户端应用导航到这个 URL 时,这没问题。 Angular 路由器会拦截这个 URL,并且把它路由到正确的页面。 +> +> 但是,当从邮件中点击链接或在浏览器地址栏中输入它或仅仅在英雄详情页刷新下浏览器时,所有这些操作都是由浏览器本身处理的,在应用的控制范围之外。 浏览器会直接向服务器请求那个 URL,路由器没机会插手。 +> +> 静态服务器会在收到对 http://www.mysite.com/ 的请求时返回 index.html,但是会拒绝对 http://www.mysite.com/heroes/42 的请求, 并返回一个 404 - Not Found 错误,除非,它被配置成了返回 index.html。 + +具体不同的服务器改怎么配置,点击链接直接看[官方文档](https://angular.cn/guide/deployment#server-configuration)吧。 + +我记得之前学 Vue 的时候,Vue 的[官方文档](https://router.vuejs.org/zh/guide/essentials/history-mode.html#%E5%90%8E%E7%AB%AF%E9%85%8D%E7%BD%AE%E4%BE%8B%E5%AD%90)也提到了这一点,只不过当时我用的是 hash 模式,这次遇到这种问题没第一时间反应过来。~~再一次被自己蠢哭了。~~ + +--- +## 后记 +官方文档永远都是最权威最完整的资料,能在官方文档中找到答案的问题,都是我们自己没认真看文档的问题。开发过程中一定要重视官方文档,可以省下去百度到处被误导的时间。 \ No newline at end of file diff --git a/简单JMeter压测.md b/简单JMeter压测.md new file mode 100644 index 0000000..69ee32b --- /dev/null +++ b/简单JMeter压测.md @@ -0,0 +1,110 @@ +# 使用 JMeter 做简单的压测 + +Date: 2022/05/12 09:10 + +ZhouXY + +--- + +## 需求 + +1. 模拟:模拟生产者往 ActiveMQ 中发消息 +2. 并发:每 5 分钟发 15000 条数据 +3. 持续时长:持续 2 个小时 +4. 消息格式:消息内容为 JSON 数据,包括 **`dev_code`** *(设备号)*、**`time`** *(当前时间)*、**dev_name** *(设备名称)* + - **dev_code** 从 100 个字符串中随机选择 + - **time** 为当前时间的字符串,格式为 `yyyy-MM-dd HH:mm:ss.SSS` + - **dev_name** 为 `DEV_NAME` 加上递增的整数 + +## 步骤 + +1. 打开 JMeter,有一个默认为空的测试计划 Test Plan,修改其名称,如:ActiveMQ 压测 Demo +2. 在测试计划中创建一个线程组 +3. 在线程组中创建事务控制器 +4. 在事务控制器中一次创建 **计数器**、**BeanShell 取样器**、**JMS Publisher** +5. 在 JMS Publisher 中创建一个 `Precise Throughput Timer`,即准确的吞吐量定时器。 + +## 线程组和定时器 + +线程组和定时器控制并发量和持续时间。 + +由于 JMeter 创建线程是不间断的,所以需要定时器。这里使用 Precise Throughput Timer 可以比较好地控制。 + +按照要求,测试结束时,应发送了 360000 条数据,实际测试可能会多几百条,误差还是相对较少的。 + +### 线程组 + +1. 线程属性的`线程数`填 500,`Ramp-Up时间(秒)`填 10,表示 **10 秒内创建 500 个线程**。我一开始直接填 300 秒(5 分钟)创建 15000 个线程,结果发送一段时间后,就会出现部分数据发送失败,暂时不知道原因。请根据自己的需要调整。 +2. 循环次数勾选 `永远` +3. 勾选下面的`调度器`选项,`持续时间(秒)`填 `7200`,表示 2 个小时 + +### 定时器 + +1. 目标吞吐量:15000 +2. 吞吐量周期:300 +3. 测试持续时间:7200 +4. 其它保持不变即可 + +## 计数器 + +由于 **dev_name** 中需要一个递增的整数,所以我们设置了计数器,最小值我设置为 1,递增为 1,引用名称为 `num`。 + +这样,JMS Publisher 中的内容就可以以 `${num}` 的形式使用该计数器的值。 + +## BeanShell 取样器 + +BeanShell 取样器可以使用 Java 的写法生成数据,然后放到“变量”中,供其它取样器使用。**dev_code** 的值是从 100 个字符串中随机选择,BeanShell 取样器要做的就是从 100 和字符串中随机选择一个,放到变量 `dev_code` 中。脚本如下所示: + +```java +import java.util.Random; + +String[] devCodes = { + "A1p8wu9iBt", "A9VzXBaFIJ", "ASKb08oVnr", "Ae2ifNTN9b", "AgpzQ8aNbt", + "Bh5CBlP4ot", "Bo7RE8Sl8Y", "BrxCJ85ETL", "BL3HF89URd", "Bs1Ij2LAHj", + "CzLJmZrfkM", "C4rmU81HCC", "CyH5il1W39", "Cn8D2aiVV8", "CX8nbIsB50", + "D4oGv91ePj", "DGxYsqTcXK", "DUyFsC5Drx", "DR6MpJJaDj", "DuH37e1jZ8", + "EYvQ6sJvhU", "E8FgaOGEc9", "Ey4Wfjj1gs", "EKC1oKFvmb", "Ec2vHlrBb4", + "FWN6vGoqnQ", "F8BbYS9l0I", "FzWxDecBOe", "FnjId6wkyw", "FJXFE9fcVg", + "GbhQiY6RIf", "GBHdz2QifF", "Gxy9Nr7SE6", "GyUtw6nbte", "GogX2WX36O", + "HxagCSigXb", "HWMhH7jWar", "H4sGFmP1Oi", "HIlL8LgwpQ", "HxB1KIPmU9", + "I57qZxE3FU", "I6ghZSfeQS", "IE0o7RF4jD", "IahpQHwBeq", "IaIAIEPHeA", + "JBfTrmIMAM", "JuZPRFKLqv", "J514XwwJRh", "JIXav0i4sF", "JhOW0JqoTX", + "KcWpYmJ5O6", "KDIpmm8IM8", "KIM10uv0HC", "KNtsRI9nWS", "KiuaJ6axgB", + "LxV7kYcam8", "LPxgMsC9v0", "LHT2biCDUg", "LKTGKDRh7q", "LY7XgPcpHi", + "MFV3F7iZTW", "MUEBypwmK9", "MRKFcfPHQt", "MVHMA2icrK", "MGivy5wulf", + "NzuMjdPtns", "N3bGBHlVnn", "NQc9WVJcO2", "N9sV5JrjYw", "NrdFpm8SLc", + "OncgB1XRyt", "OkvCZNPBft", "O2xfZ2UNTy", "OHYm0xpbsN", "ORNSHzP1TG", + "PSvqG70T2e", "PvZL2OpA1T", "PpqjV93fl8", "PAPtqDahqS", "Py6pWjF7hi", + "QyrG0AYK0T", "QOVP9hKuIN", "QNT02cVBU2", "QjyWUmVCpl", "QF5vNIMKxM", + "RrZZAxOSJJ", "RCfXSwKY1i", "R0XGiHreU4", "RmC7iQvIuU", "RdtzQ7T9cK", + "SM9dzy31hS", "SI9SykQ8Ex", "SCx73KMyOT", "SKXwIrPJdr", "SlVDhvrb4d", + "T4qXJdmRD9", "TKiDzobds3", "T8TRTHiQ42", "TKvTq2p7Dg", "TPYxtA1wz4" +}; +Random random = new Random(); + +vars.put("devCode", devCodes[random.nextInt(devCodes.length)]); +``` + +这样,JMS Publisher 中的内容就可以以 `${devCode}` 的形式使用随机选取的字符串。 + +## JMS Publisher + +- Initial Context Factory:org.apache.activemq.jndi.ActiveMQInitialContextFactory +- Provider URL:填写 Active MQ 的 URL,如:tcp://localhost:61616 +- Use Authorization:勾选 Use Authorization 并填写 用户 和 密码 +- Connection Factory:ConnectionFactory +- Destination + - 如果是 Topic,则为 `dynamicTopics/${TopicName}`,如 `dynamicTopics/topic.dev.info` + - 如果是 Queue,则为 `dynamicQueues/${QueueName}`,如 `dynamicQueues/topic.dev.info` +- 消息内容 + ```json + { + "dev_code": "${devCode}", + "dev_name": "DEV_NAME${num}", + "time": "${__time(yyyy-MM-dd HH:mm:ss.SSS,)}" + } + ``` + +## 监听器 + +监听器可以对数据发送的数据进行统计,可以在该线程组下添加需要的监听器。 \ No newline at end of file