diff --git a/Java/Java问题排查和性能优化/04 1.Jmeter压测工具.md b/Java/Java问题排查和性能优化/04 1.Jmeter压测工具.md new file mode 100644 index 00000000..de6c9ce9 --- /dev/null +++ b/Java/Java问题排查和性能优化/04 1.Jmeter压测工具.md @@ -0,0 +1,425 @@ +## 1 为什么性能测试 + +### 概述 + +软件性能测试是一种非功能性测试,其中应用程序的性能在预期或更高负载下进行评估。 +进行性能测试以测量系统的不同性能属性,如响应时间(速度),可靠性,资源使用,可扩展性,各种负载条件下的稳定性等。 + +### 基本功能 + +JMeter也称为“Apache JMeter”,它是一个开源的,100%基于Java的应用程序,带有图形界面。 它旨在分析和衡量Web应用程序和各种服务的性能和负载功能行为。 + +JMeter主要用于测试Web应用程序或FTP应用程序,但目前,它适用于功能测试,JDBC数据库连接,Web服务,通用TCP连接和OS本机进程。 您可以执行各种测试活动,如性能,负载,压力,回归和功能测试,以便针对您的Web服务器获得准确的性能指标。 + +* Web Services - SOAP / XML-RPC +* Web - HTTP, HTTPS sites ‘web 1.0’ web 2.0 (ajax, flex 和 flex-ws-amf) +* 通过JDBC驱动程序的数据库 +* 目录 - LDAP +* 通过JMS面向消息传递的服务 +* 服务 - POP3, IMAP, SMTP + +## 2 使用教程 + +### 基本界面 + +![主界面](image/image-1.png) + +## 3 核心概念 + +> https://www.yiibai.com/jmeter/build-jmeter-test-plan.html + +* 测试计划(TestPlans) + + * 线程组(Thread Groups) + + * 采样器(Samplers) + * 监听器 + * 配置文件 + * 监听器 + * 配置文件 + * 监听器 + * 配置文件 + + +### 1. 测试计划 + +测试计划:可以将测试计划可视化为用于运行测试的JMeter脚本。测试计划由测试元素组成,例如线程组,逻辑控制器,样本生成控制器,监听器,定时器,断言和配置元素。每个测试计划中至少应有一个线程组。 我们可以根据要求添加或删除元素。 + +* JMeter文件或测试计划以 `.JMX`扩展文件的形式保存。JMX是一种基于开放测试的格式,它使测试计划能够在文本编辑器中启动。 +* “测试计划(Test plan)”节点包含测试计划的名称和用户定义的变量。当您在测试计划的多个部分中有重复值时,可使用用户定义变量,它提供了灵活性。 + +![1712477758187](image/04Jmeter压测工具/1712477758187.png) + +### 2. 线程组 +线程组:线程组表示JMeter在测试期间将使用的线程组。 线程组元素是任何测试计划的起点。 +* 线程数:虚拟用户数。一个虚拟用户占用一个进程或线程。模拟多少用户访问也就填写多少个线程数量。 + +* Ramp-Up时间(秒):设置的虚拟用户数需要多长时间全部启动。如果线程数为100,准备时长为5,那么需要5秒钟启动100个线程,也就是每秒钟启动20个线程。 相当于每秒模拟20个用户进行访问,设置为零我理解为并发访问。 + +* 循环次数:如果线程数为100,循环次数为100。那么总请求数为100*100=10000 。如果勾选了“永远”,那么所有线程会一直发送请求,直到选择停止运行脚本。 + +![线程组添加界面](image/image-2.png) + +![线程组](image/image.png) + +### 3. 采样器 +控制器—采样器:采样器是允许JMeter将特定类型的请求发送到服务器的组件。它模拟用户对目标服务器的页面的请求。 + +* 采样器是必须将组件添加到测试计划中的,因为它只能让JMeter知道需要将哪种类型的请求发送到服务器。 请求可以是HTTP,HTTP(s),FTP,TCP,SMTP,SOAP等。 + +http采样器支持以下的配置内容: + +* 协议:向目标服务器发送HTTP请求协议,可以是HTTP或HTTPS,默认为HTTP。 + +* 服务器名称或IP :HTTP请求发送的目标服务器名称或IP。 + +* 端口号:目标服务器的端口号,默认值为80 + +* 方法:发送HTTP请求的方法,可用方法包括GET、POST、HEAD、PUT、OPTIONS、TRACE、DELETE等。 + +* 路径:目标URL路径(URL中去掉服务器地址、端口及参数后剩余部分)。 + +* 内容编码:编码方式,默认为ISO-8859-1编码,这里配置为utf-8。 + +* 参数:同请求一起发送参数 ,在请求中发送的URL参数,用户可以将URL中所有参数设置在本表中,表中每行为一个参数(对应URL中的 key=value),注意参数传入中文时需要勾选“编码”。 + + +添加请求。右键点击 “你的线程组” → “添加” → “取样器” → “HTTP请求” + +![添加http采样器](image/image-11.png) + +填写接口请求参数,我这里对本地的 Spring-boot 服务进行测试(本教程所用demo源码在文章最后),可以参考下图填写: +![示例http采样器](image/image-10.png) + + + +### 4. 监听器 +监听器:性能测试就是以各种形式分析服务器响应,然后将其呈现给客户端。当JMeter的采样器组件被执行时,监听器提供JMeter收集的关于那些测试用例的数据的图形表示。它便于用户在某些日志文件中以表格,图形,树或简单文本的形式查看采样器结果。监听器可以在测试的任何地方进行调整,直接包括在测试计划下。JMeter提供了大约15个监听器,但主要使用的是表,树和图形。 + +* 图表结果 +* 样条曲线可视化器 +* 断言结果 +* 简单的数据编写者 +* 监控结果 +* 分布图(alpha) +* 聚合图 +* 梅勒展示台 +* BeanShell监听器 +* 总结报告 +* 示例结果保存配置 +* 图表完整结果 +* 查看结果树 +* 汇总报告 +* 查看表格中的结果 + + +添加监听器。右键点击 “你的线程组” → “添加” → “监听器” → “察看结果树” + +![添加监听器](image/image-5.png) + +添加结果。这里,我们修改响应数据格式(你返回什么格式就选什么,我这里是返回json),运行Http请求,可以看到本次请求返回的响应数据。 + +![查看结果树](image/image-6.png) + + + +常用的内置变量 + + + + +### 5. 配置元素 +配置:配置元素的工作与采样器的工作类似。但是,它不发送请求,但它允许修改采样器发出的请求。这是一个简单的元素,您可以在其中收集所有采样器的关联配置值,如webserver的主机名或数据库URL等。配置元素只能从放置元素的分支内部访问。 + +* Java请求默认值 +* LDAP请求默认值 +* LDAP扩展请求默认值 +* 密钥库配置 +* JDBC连接配置 +* 登录配置元素 +* CSV数据集配置 +* FTP请求默认值 +* TCP采样器配置 +* 用户定义的变量 +* HTTP授权管理器 +* HTTP缓存管理器 +* HTTP Cookie管理器 +* HTTP代理服务器 +* HTTP请求默认值 +* HTTP标头管理器 +* 简单的配置元素 +* 随机变量 +* 用户自定义变量 + + +添加用户自定义变量 + +添加用户自定义变量用以Http请求参数化,右键点击 “你的线程组” → “添加” → “配置元件” → “用户定义的变量”: +![配置元件](image/image-7.png) + +自定义用户变量。新增一个用户名参数(与你实际请求参数key对应,做过接口测试的应该特别明白) + + +![新增用户自定义变量](image/image-8.png) + + +使用自定义变量。在Http请求中使用该参数,格式为:${key} ,例如: + +![使用用户自定义变量](image/image-9.png) + +### 6. 断言 + +json断言(因为我这里返回是json,其他需求更据实际情况选择) + +添加断言:右键点击 “你的HTTP请求” → “添加” → “断言” → “json断言” + +![alt text](image/image-12.png) + +配置json断言具体内容 + +![alt text](image/image-13.png) + + +配置断言结果。右键点击 “你的HTTP请求” → “添加” → “监听器” → “断言结果” + +![配置断言结果](image/image-14.png) + +查看断言结果 + +![断言结果](image/image-15.png) + + +### 7. 聚合报告 + +添加聚合报告 + +右键点击 “你的线程组” → “添加” → “监听器” → “聚合报告”,用以存放性能测试报告 + +![添加聚合报告](image/image-16.png) + +### 8. 控制器 +控制器-逻辑控制器:逻辑控制器可帮助您控制线程中采样器处理顺序的流程。 它还可以更改来自其子元素的请求的顺序。 + +* 运行时控制器 +* IF控制器 +* 事务控制器 +* 录音控制器 +* 简单控制器 +* while控制器 +* Switch控制器 +* ForEach控制器 +* 模块控制器 +* 包括控制器 +* 循环控制器 +* 仅一次控制器 +* 交错控制器 +* 随机控制器 +* 随机顺序控制器 +* 吞吐量控制器 + + +### 9. 预处理器和后处理器 +预处理器元素在采样器发出请求之前执行,如果预处理器附加到采样器元素,那么它将在该采样器元素运行之前执行。 +预处理器元素用于在运行之前修改样本请求的设置,或更新未从响应文本中提取的变量。 +以下是JMeter提供的所有预处理器元素的列表: + + + +* JDBC预处理器 +* JSR223预处理器 +* RegEx用户参数 +* BeanShell预处理器 +* BSF预处理器 +* HTML链接解析器 +* HTTP URL重写修饰符 +* HTTP用户参数修饰符 +* 用户参数 + + +### 10. 后处理器 +在发出采样器请求之后执行后处理器元素。 如果后处理器连接到Sampler元素,那么它将在该sampler元素运行之后执行。 + +后处理器最常用于处理响应数据,例如,为了将来目的而提取特定值。 + +下面给出了JMeter提供的所有后处理器元素的列表: + +* CSS/JQuery抽取器 +* BeanShell后处理器 +* JSR223后处理器 +* JDBC后处理器 +* 调试后处理器 +* 正则表达式提取器 +* XPath抽取器 +* 结果状态操作处理程序 +* BSF后处理器 + + + +## 4 脚本启动命令 + +在服务器上一版使用命令行启动测试脚本。 + +使用命令行启动 JMeter 时,可以通过命令行参数来配置 JMeter 的运行方式,比如设置测试计划文件、日志文件、执行模式以及各种系统属性等。以下是一些常用的 JMeter 命令行启动参数: + +* `-n`:指定 JMeter 以**非图形界面模式**运行,适用于批量运行或分布式测试。 +* `-t [测试计划.jmx]`:指定 JMeter 测试计划文件的路径。 +* `-l [结果文件.jtl]`:指定 JMeter 测试结果的输出文件路径。 +* `-j [日志文件.log]`:指定 JMeter 运行日志的输出文件路径。 +* `-r`:告诉 JMeter 的 Master 连接到定义在 `jmeter.properties` 文件中的远程 Slave 服务器。只有在 `-n` 也被指定时才能使用 `-r`。 +* `-R [逗号分隔的服务器列表]`:指定远程 Slave 服务器的列表,用于分布式测试。如 `-R 192.168.0.1,192.168.0.2`。 +* `-d [目录]`:指定 JMeter 的“起始目录”,即 JMeter 将在该目录下查找用户类路径和插件。 +* `-p [属性文件]`:指定 JMeter 属性文件的路径,通常是 `jmeter.properties` 文件。 +* `-q [额外属性文件]`:指定一个额外的 JMeter 属性文件,可以用于覆盖默认的属性设置。 +* `-J[属性名]=[值]`:直接在命令行中设置某个 JMeter 属性的值,如 `-JthreadNum=10` 设置属性 `threadNum` 的值为 10。 +* `-G[属性名]=[值]`:用于分布式测试,给远程的 Slave 服务器设置全局属性。 +* `-e`:在测试完成后以图形界面模式打开生成的报告分析数据。 +* `-o [输出目录]`:指定输出文件夹,用于存放使用 `-e` 参数生成的 HTML 报告。如果文件夹不存在,JMeter 将会创建它。 +* `-H [代理主机名]` 和 `-P [代理端口]`:配置 JMeter 使用代理服务器,如 `-H my.proxy.server -P 8000` 指定代理服务器。 +* `-u` 和 `-a`:指定订阅和发布的令牌(JMeter 5.0 引入)。 + +典型的启动命令如下 + +jmeter -n -t /path/to/your/testplan.jmx -l /path/to/resultsfile.jtl + +## 5 使用实例 + +web的使用实例: + +https://www.yiibai.com/jmeter/jmeter-web-test-plan.html + +https://blog.csdn.net/DY_CSDN/article/details/130016640 + + +在 JMeter 中,从返回值中提取变量并将其用于后续请求是一个常见的需求。例如,从 JSON 或 XML 响应中提取一个字段的值(如用户 ID、Token 等),然后将该值作为参数传递给后续请求。以下是实现这一功能的详细步骤和方法: + +--- + +## 6 使用后置处理器提取变量 + +JMeter 提供了多种后置处理器(Post-Processor)来解析响应数据并提取变量。根据响应格式的不同,可以选择合适的后置处理器。 + +### 1. **JSON 响应:使用 JSON Extractor** +如果响应是 JSON 格式,可以使用 **JSON Extractor** 提取字段值。 + +#### 配置步骤: +1. 在需要提取变量的 HTTP 请求下添加 **JSON Extractor**: + - 右键点击请求 -> 添加 -> 后置处理器 -> JSON Extractor。 +2. 配置 JSON Extractor: + - **Names of created variables**:定义提取变量的名称(如 `userId`)。 + - **JSON Path Expressions**:填写 JSONPath 表达式,定位目标字段。 + - 示例:`$.data.id` 提取 `data` 对象中的 `id` 字段。 + - **Match No.**:指定匹配的索引(0 表示随机匹配,1 表示第一个匹配项)。 + - **Default Value**:如果未找到匹配项时的默认值。 + +#### 示例响应: +```json +{ + "status": "success", + "data": { + "id": 123, + "name": "John Doe" + } +} +``` +- JSONPath 表达式:`$.data.id` +- 提取的值:`123` + +#### 使用变量: +在后续请求中,可以通过 `${userId}` 引用提取的值。 + +--- + +### 2. **XML 响应:使用 XPath Extractor** +如果响应是 XML 格式,可以使用 **XPath Extractor** 提取字段值。 + +#### 配置步骤: +1. 在需要提取变量的 HTTP 请求下添加 **XPath Extractor**: + - 右键点击请求 -> 添加 -> 后置处理器 -> XPath Extractor。 +2. 配置 XPath Extractor: + - **Reference Name**:定义提取变量的名称(如 `userId`)。 + - **XPath Query**:填写 XPath 表达式,定位目标字段。 + - 示例:`/response/data/id` 提取 `` 元素的值。 + - **Default Value**:如果未找到匹配项时的默认值。 + +#### 示例响应: +```xml + + success + + 123 + John Doe + + +``` +- XPath 表达式:`/response/data/id` +- 提取的值:`123` + +#### 使用变量: +在后续请求中,可以通过 `${userId}` 引用提取的值。 + +--- + +### 3. **正则表达式:使用 Regular Expression Extractor** +如果响应格式不固定(如 HTML 或非结构化文本),可以使用 **Regular Expression Extractor** 提取字段值。 + +#### 配置步骤: +1. 在需要提取变量的 HTTP 请求下添加 **Regular Expression Extractor**: + - 右键点击请求 -> 添加 -> 后置处理器 -> Regular Expression Extractor。 +2. 配置 Regular Expression Extractor: + - **Reference Name**:定义提取变量的名称(如 `userId`)。 + - **Regular Expression**:填写正则表达式,匹配目标字段。 + - 示例:`"id":\s*"(\d+)"` 提取 JSON 中的 `id` 字段。 + - **Template**:指定提取的内容(通常为 `$1$` 表示第一个捕获组)。 + - **Match No.**:指定匹配的索引(0 表示随机匹配,1 表示第一个匹配项)。 + - **Default Value**:如果未找到匹配项时的默认值。 + +#### 示例响应: +```json +{ + "status": "success", + "data": { + "id": 123, + "name": "John Doe" + } +} +``` +- 正则表达式:`"id":\s*"(\d+)"` +- 提取的值:`123` + +#### 使用变量: +在后续请求中,可以通过 `${userId}` 引用提取的值。 + +--- + +### 4. **调试提取结果** + +为了确保变量提取正确,可以使用以下工具进行调试: +1. **Debug Sampler**: + - 添加一个 Debug Sampler,查看所有变量的值。 +2. **View Results Tree**: + - 查看响应内容和提取的变量值。 + +--- + +### 5. **在后续请求中使用提取的变量** + +提取的变量可以直接在后续请求中引用。例如: +- **HTTP 请求参数**: + ```plaintext + userId=${userId} + ``` +- **HTTP 请求路径**: + ```plaintext + http://example.com/api/user/${userId} + ``` +- **HTTP 请求头**: + ```plaintext + Authorization: Bearer ${token} + ``` + + +## 7 异步测试(循环控制器+正则表达式+BeanShell) + +> https://blog.csdn.net/u011320832/article/details/88060106 +> https://blog.csdn.net/okcross0/article/details/145753556 + diff --git a/Java/Java问题排查和性能优化/04 2.Jmeter常用变量.md b/Java/Java问题排查和性能优化/04 2.Jmeter常用变量.md new file mode 100644 index 00000000..e8cbfa0c --- /dev/null +++ b/Java/Java问题排查和性能优化/04 2.Jmeter常用变量.md @@ -0,0 +1,230 @@ +JMeter 提供了许多内置变量,这些变量可以在测试计划中直接使用,用于动态生成数据、控制测试逻辑或获取运行时信息。以下是 JMeter 中常见的内置变量及其用途的详细说明: + +--- + +## 一、**线程和用户相关的变量** + +1. **`__threadNum`** + - **作用**:返回当前线程的编号(从 1 开始)。 + - **示例**: + ```plaintext + ${__threadNum} + ``` + 如果有 3 个线程,则分别返回 `1`、`2` 和 `3`。 + +2. **`__groupThreads`** + - **作用**:返回当前线程组中的总线程数。 + - **示例**: + ```plaintext + ${__groupThreads()} + ``` + +3. **`__machineName`** + - **作用**:返回运行 JMeter 的机器名。 + - **示例**: + ```plaintext + ${__machineName} + ``` + +4. **`__machineIP`** + - **作用**:返回运行 JMeter 的机器 IP 地址。 + - **示例**: + ```plaintext + ${__machineIP} + ``` + +5. **`__P`(属性值)** + - **作用**:获取命令行参数或配置文件中定义的属性值。 + - **语法**: + ```plaintext + ${__P(propertyName, defaultValue)} + ``` + - **示例**: + 假设命令行启动时传入 `-Juser=admin`,则: + ```plaintext + ${__P(user, "defaultUser")} + ``` + 如果未设置 `user` 属性,则返回默认值 `"defaultUser"`。 + +--- + +## 二、**时间相关的变量** + +1. **`__time`** + - **作用**:返回当前时间的时间戳或格式化时间。 + - **语法**: + ```plaintext + ${__time(format)} + ``` + - **示例**: + - 默认返回时间戳(毫秒): + ```plaintext + ${__time()} + ``` + - 返回格式化时间(如 `yyyyMMddHHmmss`): + ```plaintext + ${__time(yyyyMMddHHmmss)} + ``` + 示例输出:`20231030123045` + +2. **`__RandomDate`** + - **作用**:生成随机日期。 + - **语法**: + ```plaintext + ${__RandomDate(start, end, format)} + ``` + - **示例**: + ```plaintext + ${__RandomDate(2023-01-01, 2023-12-31, yyyy-MM-dd)} + ``` + 示例输出:`2023-07-15` + +--- + +## 三、**随机数相关的变量** + +1. **`__Random`** + - **作用**:生成指定范围内的随机整数。 + - **语法**: + ```plaintext + ${__Random(min, max)} + ``` + - **示例**: + ```plaintext + ${__Random(1, 100)} + ``` + 示例输出:`42` + +2. **`__RandomString`** + - **作用**:生成指定长度的随机字符串。 + - **语法**: + ```plaintext + ${__RandomString(length, charsToUse)} + ``` + - **示例**: + ```plaintext + ${__RandomString(8, abcdefghijklmnopqrstuvwxyz)} + ``` + 示例输出:`xyzabcde` + +3. **`__UUID`** + - **作用**:生成一个随机的 UUID。 + - **语法**: + ```plaintext + ${__UUID()} + ``` + - **示例**: + ```plaintext + ${__UUID()} + ``` + 示例输出:`550e8400-e29b-41d4-a716-446655440000` + +--- + +## 四、**系统和环境相关的变量** + +1. **`__javaScript`** + - **作用**:执行 JavaScript 表达式并返回结果。 + - **语法**: + ```plaintext + ${__javaScript(expression)} + ``` + - **示例**: + ```plaintext + ${__javaScript(Math.random() * 100)} + ``` + 示例输出:`42.123456789` + +2. **`__env`** + - **作用**:返回操作系统环境变量的值。 + - **语法**: + ```plaintext + ${__env(variableName)} + ``` + - **示例**: + ```plaintext + ${__env(USER)} + ``` + 示例输出:`admin` + +3. **`__groovy`** + - **作用**:执行 Groovy 脚本并返回结果。 + - **语法**: + ```plaintext + ${__groovy(script)} + ``` + - **示例**: + ```plaintext + ${__groovy(new Date().format("yyyy-MM-dd"))} + ``` + 示例输出:`2023-10-30` + +4. **`__systemProperty`** + - **作用**:返回 JVM 系统属性的值。 + - **语法**: + ```plaintext + ${__systemProperty(propertyName)} + ``` + - **示例**: + ```plaintext + ${__systemProperty(os.name)} + ``` + 示例输出:`Windows 10` + +--- + +## 五、**其他常用变量** + +1. **`__counter`** + - **作用**:生成一个递增的计数器。 + - **语法**: + ```plaintext + ${__counter(perThread, startValue)} + ``` + - **示例**: + - 每个线程独立计数: + ```plaintext + ${__counter(TRUE, 1)} + ``` + - 全局计数: + ```plaintext + ${__counter(FALSE, 1)} + ``` + +2. **`__split`** + - **作用**:将字符串按分隔符拆分为多个部分,并存储到变量中。 + - **语法**: + ```plaintext + ${__split(string, variableName, delimiter)} + ``` + - **示例**: + ```plaintext + ${__split(a,b,c,d, myVar, ,)} + ``` + 结果: + - `myVar_1 = a` + - `myVar_2 = b` + - `myVar_3 = c` + - `myVar_4 = d` + +3. **`__property`** + - **作用**:返回 JMeter 属性的值。 + - **语法**: + ```plaintext + ${__property(propertyName, defaultValue)} + ``` + - **示例**: + ```plaintext + ${__property(user.properties.myKey, "defaultValue")} + ``` + +--- + +## 六、**总结** + +JMeter 的内置变量非常丰富,涵盖了时间、随机数、系统信息、计数器等多个方面。以下是一些常见的应用场景: +- **动态生成数据**:如时间戳、随机数、UUID。 +- **获取运行时信息**:如线程号、机器名、环境变量。 +- **参数化测试**:通过属性或计数器实现动态参数化。 + +如果你需要更具体的变量或功能,请提供你的测试场景,我可以为你提供更详细的解决方案! \ No newline at end of file diff --git a/Java/Java问题排查和性能优化/04 Jmeter压测工具.md b/Java/Java问题排查和性能优化/04 3.自定义请求和搭建集群.md similarity index 55% rename from Java/Java问题排查和性能优化/04 Jmeter压测工具.md rename to Java/Java问题排查和性能优化/04 3.自定义请求和搭建集群.md index f308e117..728e6978 100644 --- a/Java/Java问题排查和性能优化/04 Jmeter压测工具.md +++ b/Java/Java问题排查和性能优化/04 3.自定义请求和搭建集群.md @@ -1,197 +1,3 @@ -## 1 为什么性能测试 - -### 概述 - -软件性能测试是一种非功能性测试,其中应用程序的性能在预期或更高负载下进行评估。 -进行性能测试以测量系统的不同性能属性,如响应时间(速度),可靠性,资源使用,可扩展性,各种负载条件下的稳定性等。 - -### 基本功能 - -JMeter也称为“Apache JMeter”,它是一个开源的,100%基于Java的应用程序,带有图形界面。 它旨在分析和衡量Web应用程序和各种服务的性能和负载功能行为。 - -JMeter主要用于测试Web应用程序或FTP应用程序,但目前,它适用于功能测试,JDBC数据库连接,Web服务,通用TCP连接和OS本机进程。 您可以执行各种测试活动,如性能,负载,压力,回归和功能测试,以便针对您的Web服务器获得准确的性能指标。 - -* Web Services - SOAP / XML-RPC -* Web - HTTP, HTTPS sites ‘web 1.0’ web 2.0 (ajax, flex 和 flex-ws-amf) -* 通过JDBC驱动程序的数据库 -* 目录 - LDAP -* 通过JMS面向消息传递的服务 -* 服务 - POP3, IMAP, SMTP - -## 2 使用教程 - -### 基本界面 - -![](https://www.yiibai.com/uploads/images/2018/08/01/171458_22860.png) - -### 核心概念 - -> https://www.yiibai.com/jmeter/build-jmeter-test-plan.html - -* 测试计划(TestPlans) - - * 线程组(Thread Groups) - - * 采样器(Samplers) - * 监听器 - * 配置文件 - * 监听器 - * 配置文件 - * 监听器 - * 配置文件 - -![img](https://www.yiibai.com/uploads/article/2018/08/02/160226_93320.png) - -测试计划:可以将测试计划可视化为用于运行测试的JMeter脚本。测试计划由测试元素组成,例如线程组,逻辑控制器,样本生成控制器,监听器,定时器,断言和配置元素。每个测试计划中至少应有一个线程组。 我们可以根据要求添加或删除元素。 - -* JMeter文件或测试计划以 `.JMX`扩展文件的形式保存。JMX是一种基于开放测试的格式,它使测试计划能够在文本编辑器中启动。 -* “测试计划(Test plan)”节点包含测试计划的名称和用户定义的变量。当您在测试计划的多个部分中有重复值时,可使用用户定义变量,它提供了灵活性。 - -![1712477758187](image/04Jmeter压测工具/1712477758187.png) - -线程组:线程组表示JMeter在测试期间将使用的线程组。 线程组元素是任何测试计划的起点。 - -* 设置线程数。 -* 设置加速期。 -* 设置执行测试的次数。 - -![](https://www.yiibai.com/uploads/images/2018/08/02/170253_30401.png) - -控制器—采样器:采样器是允许JMeter将特定类型的请求发送到服务器的组件。它模拟用户对目标服务器的页面的请求。 - -* 采样器是必须将组件添加到测试计划中的,因为它只能让JMeter知道需要将哪种类型的请求发送到服务器。 请求可以是HTTP,HTTP(s),FTP,TCP,SMTP,SOAP等。 - -![](https://www.yiibai.com/uploads/images/2018/08/02/170925_11078.png) - -控制器-逻辑控制器:逻辑控制器可帮助您控制线程中采样器处理顺序的流程。 它还可以更改来自其子元素的请求的顺序。 - -* 运行时控制器 -* IF控制器 -* 事务控制器 -* 录音控制器 -* 简单控制器 -* while控制器 -* Switch控制器 -* ForEach控制器 -* 模块控制器 -* 包括控制器 -* 循环控制器 -* 仅一次控制器 -* 交错控制器 -* 随机控制器 -* 随机顺序控制器 -* 吞吐量控制器 - -![](https://www.yiibai.com/uploads/images/2018/08/02/171522_14436.png) - -监听器:性能测试就是以各种形式分析服务器响应,然后将其呈现给客户端。当JMeter的采样器组件被执行时,监听器提供JMeter收集的关于那些测试用例的数据的图形表示。它便于用户在某些日志文件中以表格,图形,树或简单文本的形式查看采样器结果。监听器可以在测试的任何地方进行调整,直接包括在测试计划下。JMeter提供了大约15个监听器,但主要使用的是表,树和图形。 - -* 图表结果 -* 样条曲线可视化器 -* 断言结果 -* 简单的数据编写者 -* 监控结果 -* 分布图(alpha) -* 聚合图 -* 梅勒展示台 -* BeanShell监听器 -* 总结报告 -* 示例结果保存配置 -* 图表完整结果 -* 查看结果树 -* 汇总报告 -* 查看表格中的结果 - -![](https://www.yiibai.com/uploads/article/2018/08/02/171858_59718.png) - -配置:配置元素的工作与采样器的工作类似。但是,它不发送请求,但它允许修改采样器发出的请求。这是一个简单的元素,您可以在其中收集所有采样器的关联配置值,如webserver的主机名或数据库URL等。配置元素只能从放置元素的分支内部访问。 - -* Java请求默认值 -* LDAP请求默认值 -* LDAP扩展请求默认值 -* 密钥库配置 -* JDBC连接配置 -* 登录配置元素 -* CSV数据集配置 -* FTP请求默认值 -* TCP采样器配置 -* 用户定义的变量 -* HTTP授权管理器 -* HTTP缓存管理器 -* HTTP Cookie管理器 -* HTTP代理服务器 -* HTTP请求默认值 -* HTTP标头管理器 -* 简单的配置元素 -* 随机变量 - -![](https://www.yiibai.com/uploads/article/2018/08/02/175205_28314.png) - -预处理器元素在采样器发出请求之前执行,如果预处理器附加到采样器元素,那么它将在该采样器元素运行之前执行。 -预处理器元素用于在运行之前修改样本请求的设置,或更新未从响应文本中提取的变量。 -以下是JMeter提供的所有预处理器元素的列表: - -* JDBC预处理器 -* JSR223预处理器 -* RegEx用户参数 -* BeanShell预处理器 -* BSF预处理器 -* HTML链接解析器 -* HTTP URL重写修饰符 -* HTTP用户参数修饰符 -* 用户参数 - -![](https://www.yiibai.com/uploads/images/2018/08/02/175631_46005.png) - -在发出采样器请求之后执行后处理器元素。 如果后处理器连接到Sampler元素,那么它将在该sampler元素运行之后执行。 - -后处理器最常用于处理响应数据,例如,为了将来目的而提取特定值。 - -下面给出了JMeter提供的所有后处理器元素的列表: - -* CSS/JQuery抽取器 -* BeanShell后处理器 -* JSR223后处理器 -* JDBC后处理器 -* 调试后处理器 -* 正则表达式提取器 -* XPath抽取器 -* 结果状态操作处理程序 -* BSF后处理器 - -![](https://www.yiibai.com/uploads/article/2018/08/02/180931_39141.png) - -### 启动命令 - -在服务器上一版使用命令行启动测试脚本。 - -使用命令行启动 JMeter 时,可以通过命令行参数来配置 JMeter 的运行方式,比如设置测试计划文件、日志文件、执行模式以及各种系统属性等。以下是一些常用的 JMeter 命令行启动参数: - -* `-n`:指定 JMeter 以**非图形界面模式**运行,适用于批量运行或分布式测试。 -* `-t [测试计划.jmx]`:指定 JMeter 测试计划文件的路径。 -* `-l [结果文件.jtl]`:指定 JMeter 测试结果的输出文件路径。 -* `-j [日志文件.log]`:指定 JMeter 运行日志的输出文件路径。 -* `-r`:告诉 JMeter 的 Master 连接到定义在 `jmeter.properties` 文件中的远程 Slave 服务器。只有在 `-n` 也被指定时才能使用 `-r`。 -* `-R [逗号分隔的服务器列表]`:指定远程 Slave 服务器的列表,用于分布式测试。如 `-R 192.168.0.1,192.168.0.2`。 -* `-d [目录]`:指定 JMeter 的“起始目录”,即 JMeter 将在该目录下查找用户类路径和插件。 -* `-p [属性文件]`:指定 JMeter 属性文件的路径,通常是 `jmeter.properties` 文件。 -* `-q [额外属性文件]`:指定一个额外的 JMeter 属性文件,可以用于覆盖默认的属性设置。 -* `-J[属性名]=[值]`:直接在命令行中设置某个 JMeter 属性的值,如 `-JthreadNum=10` 设置属性 `threadNum` 的值为 10。 -* `-G[属性名]=[值]`:用于分布式测试,给远程的 Slave 服务器设置全局属性。 -* `-e`:在测试完成后以图形界面模式打开生成的报告分析数据。 -* `-o [输出目录]`:指定输出文件夹,用于存放使用 `-e` 参数生成的 HTML 报告。如果文件夹不存在,JMeter 将会创建它。 -* `-H [代理主机名]` 和 `-P [代理端口]`:配置 JMeter 使用代理服务器,如 `-H my.proxy.server -P 8000` 指定代理服务器。 -* `-u` 和 `-a`:指定订阅和发布的令牌(JMeter 5.0 引入)。 - -典型的启动命令如下 - -jmeter -n -t /path/to/your/testplan.jmx -l /path/to/resultsfile.jtl - -## 3 使用实例 - -web的使用实例: - -https://www.yiibai.com/jmeter/jmeter-web-test-plan.html ## 4 自定义Jmeter采样器 diff --git a/Java/Java问题排查和性能优化/image/image-1.png b/Java/Java问题排查和性能优化/image/image-1.png new file mode 100644 index 00000000..cd19f38a Binary files /dev/null and b/Java/Java问题排查和性能优化/image/image-1.png differ diff --git a/Java/Java问题排查和性能优化/image/image-10.png b/Java/Java问题排查和性能优化/image/image-10.png new file mode 100644 index 00000000..069a546c Binary files /dev/null and b/Java/Java问题排查和性能优化/image/image-10.png differ diff --git a/Java/Java问题排查和性能优化/image/image-11.png b/Java/Java问题排查和性能优化/image/image-11.png new file mode 100644 index 00000000..d2a7bda7 Binary files /dev/null and b/Java/Java问题排查和性能优化/image/image-11.png differ diff --git a/Java/Java问题排查和性能优化/image/image-12.png b/Java/Java问题排查和性能优化/image/image-12.png new file mode 100644 index 00000000..6ba36257 Binary files /dev/null and b/Java/Java问题排查和性能优化/image/image-12.png differ diff --git a/Java/Java问题排查和性能优化/image/image-13.png b/Java/Java问题排查和性能优化/image/image-13.png new file mode 100644 index 00000000..5f22cdc0 Binary files /dev/null and b/Java/Java问题排查和性能优化/image/image-13.png differ diff --git a/Java/Java问题排查和性能优化/image/image-14.png b/Java/Java问题排查和性能优化/image/image-14.png new file mode 100644 index 00000000..0c4e70ca Binary files /dev/null and b/Java/Java问题排查和性能优化/image/image-14.png differ diff --git a/Java/Java问题排查和性能优化/image/image-15.png b/Java/Java问题排查和性能优化/image/image-15.png new file mode 100644 index 00000000..a6849a6f Binary files /dev/null and b/Java/Java问题排查和性能优化/image/image-15.png differ diff --git a/Java/Java问题排查和性能优化/image/image-16.png b/Java/Java问题排查和性能优化/image/image-16.png new file mode 100644 index 00000000..91404072 Binary files /dev/null and b/Java/Java问题排查和性能优化/image/image-16.png differ diff --git a/Java/Java问题排查和性能优化/image/image-2.png b/Java/Java问题排查和性能优化/image/image-2.png new file mode 100644 index 00000000..1e5634ee Binary files /dev/null and b/Java/Java问题排查和性能优化/image/image-2.png differ diff --git a/Java/Java问题排查和性能优化/image/image-3.png b/Java/Java问题排查和性能优化/image/image-3.png new file mode 100644 index 00000000..69cc21e1 Binary files /dev/null and b/Java/Java问题排查和性能优化/image/image-3.png differ diff --git a/Java/Java问题排查和性能优化/image/image-4.png b/Java/Java问题排查和性能优化/image/image-4.png new file mode 100644 index 00000000..f867a72d Binary files /dev/null and b/Java/Java问题排查和性能优化/image/image-4.png differ diff --git a/Java/Java问题排查和性能优化/image/image-5.png b/Java/Java问题排查和性能优化/image/image-5.png new file mode 100644 index 00000000..d6492805 Binary files /dev/null and b/Java/Java问题排查和性能优化/image/image-5.png differ diff --git a/Java/Java问题排查和性能优化/image/image-6.png b/Java/Java问题排查和性能优化/image/image-6.png new file mode 100644 index 00000000..3095b215 Binary files /dev/null and b/Java/Java问题排查和性能优化/image/image-6.png differ diff --git a/Java/Java问题排查和性能优化/image/image-7.png b/Java/Java问题排查和性能优化/image/image-7.png new file mode 100644 index 00000000..bb84d794 Binary files /dev/null and b/Java/Java问题排查和性能优化/image/image-7.png differ diff --git a/Java/Java问题排查和性能优化/image/image-8.png b/Java/Java问题排查和性能优化/image/image-8.png new file mode 100644 index 00000000..8d7cc7bc Binary files /dev/null and b/Java/Java问题排查和性能优化/image/image-8.png differ diff --git a/Java/Java问题排查和性能优化/image/image-9.png b/Java/Java问题排查和性能优化/image/image-9.png new file mode 100644 index 00000000..b27f6188 Binary files /dev/null and b/Java/Java问题排查和性能优化/image/image-9.png differ diff --git a/Java/Java问题排查和性能优化/image/image.png b/Java/Java问题排查和性能优化/image/image.png new file mode 100644 index 00000000..aaca927a Binary files /dev/null and b/Java/Java问题排查和性能优化/image/image.png differ diff --git a/Netty/01 Netty简介.md b/Netty/01 Netty简介.md index af303fb2..d79aba2d 100644 --- a/Netty/01 Netty简介.md +++ b/Netty/01 Netty简介.md @@ -8,6 +8,7 @@ Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂 Netty和Tomcat最大的区别就在于通信协议,Tomcat是基于Http协议的Servlet容器,他的实质是一个基于http协议的web容器,但是Netty不一样,他能通过编程自定义各种协议,因为netty能够通过codec自己来编码/解码字节流,完成类似redis访问的功能,这就是netty和tomcat最大的不同。 ![](image/2022-11-27-13-49-01.png) +![netty reactor原理图](image/image.png) ### 对比 Netty vs NIO,工作量大,bug 多 @@ -19,7 +20,7 @@ Netty vs NIO,工作量大,bug 多 * epoll 空轮询导致 CPU 100% * 对 API 进行增强,使之更易用,如 FastThreadLocal => ThreadLocal,ByteBuf => ByteBufferNetty更友好更强大:1、JDK中NIO的一些API功能薄弱且复杂,Netty隔离了JDK中NIO的实现变化及实现细节譬如:ByteBuffer -> ByteBuf主要负责从底层的IO中读取数据到ByteBuf,然后传递给应用程序,应用程序处理完之后封装为ByteBuf,写回给IO。 -* Netty自身线程安全:使用JDK原生API需要对多线程要很熟悉, 因为N I O 涉及到Reactor设计模式,得对里面的原理要相当的熟悉。 +* Netty自身线程安全:使用JDK原生API需要对多线程要很熟悉, 因为N I O 涉及到Reactor设计模式,得对里面的原理要相当的熟悉。 diff --git a/Netty/02 核心组件.md b/Netty/02 核心组件.md index cda8b7b4..24b0495f 100644 --- a/Netty/02 核心组件.md +++ b/Netty/02 核心组件.md @@ -14,7 +14,14 @@ > Pipeline/PipelineGroup ## 0 HelloWorld - +### 引入依赖 +```xml + + io.netty + netty-all + 4.1.20.Final + +``` ### 服务器 ```java @@ -294,8 +301,10 @@ inbound/outbound:对于数据的出站和入站,有着不同的ChannelHandle 数据传输流,与channel相关的概念有以下四个,上一张图让你了解netty里面的Channel。 -* Channel,表示一个连接,可以理解为每一个请求,就是一个Channel。ChannelFuture 一种基于回调的事件处理接口。 -* ChannelHandler,核心处理业务就在这里,用于处理业务请求。ChannelHandlerContext,用于传输业务数据。ChannelPipeline,用于保存处理过程需要用到的ChannelHandler和ChannelHandlerContext。 +* Channel,表示一个连接,可以理解为每一个请求,就是一个Channel +* ChannelFuture 一种基于回调的事件处理接口。 +* ChannelHandler,核心处理业务就在这里,用于处理业务请求 +* ChannelHandlerContext,用于传输业务数据。ChannelPipeline,用于保存处理过程需要用到的ChannelHandler和ChannelHandlerContext。 diff --git a/Netty/image/image.png b/Netty/image/image.png new file mode 100644 index 00000000..6b736731 Binary files /dev/null and b/Netty/image/image.png differ diff --git a/Nginx/01 入门.md b/Nginx/01 入门.md new file mode 100644 index 00000000..6fa2de98 --- /dev/null +++ b/Nginx/01 入门.md @@ -0,0 +1,616 @@ +## 1. Nginx +> 参考文件 https://dunwu.github.io/nginx-tutorial/#/nginx-quickstart?id=%e7%bd%91%e7%ab%99%e6%9c%89%e5%a4%9a%e4%b8%aa-webapp-%e7%9a%84%e9%85%8d%e7%bd%ae +> https://zhuanlan.zhihu.com/p/389438482 +### Nginx是什么 +Nginx (engine x) 是一款轻量级的 Web 服务器 、反向代理服务器、负载均衡及电子邮件(IMAP/POP3)代理服务器。 + +Nginx本身也是一个静态资源的服务器,当只有静态资源的时候,就可以使用Nginx来做服务器,如果一个网站只是静态页面的话,那么就可以通过这种方式来实现部署。 + +特点:轻量级、高性能、稳定性高、并发性好 + +![alt text](image/image.png) + +### mac上安装Nginx + +1. 安装命令 +``` +brew install nginx +``` +2. 启动nginx服务 +``` +brew services start nginx +``` +3. 在mac上nginx的配置目录 + +``` +``` + +## 2. 命令配置 + +### 常用命令 + +``` +nginx -s stop 快速关闭Nginx,可能不保存相关信息,并迅速终止web服务。 +nginx -s quit 平稳关闭Nginx,保存相关信息,有安排的结束web服务。 +nginx -s reload 因改变了Nginx相关配置,需要重新加载配置而重载。 +nginx -s reopen 重新打开日志文件。 +nginx -c filename 为 Nginx 指定一个配置文件,来代替缺省的。 +nginx -t 不运行,仅仅测试配置文件。nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件。 +nginx -v 显示 nginx 的版本。 +nginx -V 显示 nginx 的版本,编译器版本和配置参数。 +``` + + +### location中支持的正则表达式 + +location uri正则表达式 + +* `.` :匹配除换行符以外的任意字符 +* `?` :重复0次或1次 +* `+` :重复1次或更多次 +* `*` :重复0次或更多次 +* `\d` :匹配数字 +* `^` :匹配字符串的开始 +* `$` :匹配字符串的结束 +* `{n}` :重复n次 +* `{n,}` :重复n次或更多次 +* `[c]` :匹配单个字符c +* `[a-z]` :匹配a-z小写字母的任意一个 +* `(a|b|c)` : 属线表示匹配任意一种情况,每种情况使用竖线分隔,一般使用小括号括括住,匹配符合a字符 或是b字符 或是c字符的字符串。小括号()之间匹配的内容,可以在后面通过$1来引用,$2表示的是前面第二个()里的内容。正则里面容易让人困惑的是\转义特殊字符。 +* `\` 反斜杠:用于转义特殊字符 + + +常见的location路径映射路径有以下几种: + +* = 进行普通字符精确匹配。也就是完全匹配。 +* ^~ 前缀匹配。如果匹配成功,则不再匹配其他location。 +* ~ 表示执行一个正则匹配,区分大小写 +* ~* 表示执行一个正则匹配,不区分大小写 +* /xxx/ 常规字符串路径匹配 +* / 通用匹配,任何请求都会匹配到 + +### location优先级 +当一个路径匹配多个location时究竟哪个location能匹配到时有优先级顺序的,而优先级的顺序于location值的表达式类型有关,和在配置文件中的先后顺序无关。相同类型的表达式,字符串长的会优先匹配。 + +* 等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他匹配项,停止搜索。 +* ^~类型表达式,不属于正则表达式。一旦匹配成功,则不再查找其他匹配项,停止搜索。 +* 正则表达式类型(~ ~*)的优先级次之。如果有多个location的正则能匹配的话,则使用正则表达式最长的那个。 +* 常规字符串匹配类型。按前缀匹配。 +* / 通用匹配,如果没有匹配到,就匹配通用的 + + +优先级搜索问题:不同类型的location映射决定是否继续向下搜索 + +* 等号类型、^~类型:一旦匹配上就停止搜索了,不会再匹配其他location了 +* 正则表达式类型`(~ ~*)`,常规字符串匹配类型/xxx/ : 匹配到之后,还会继续搜索其他其它location,直到找到优先级最高的,或者找到第一种情况而停止搜索 + +location优先级从高到底: + +(location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (/) + + +``` +location = / { + # 精确匹配/,主机名后面不能带任何字符串 / + [ configuration A ] +} +location / { + # 匹配所有以 / 开头的请求。 + # 但是如果有更长的同类型的表达式,则选择更长的表达式。 + # 如果有正则表达式可以匹配,则优先匹配正则表达式。 + [ configuration B ] +} +location /documents/ { + # 匹配所有以 /documents/ 开头的请求,匹配符合以后,还要继续往下搜索。 + # 但是如果有更长的同类型的表达式,则选择更长的表达式。 + # 如果有正则表达式可以匹配,则优先匹配正则表达式。 + [ configuration C ] +} +location ^~ /images/ { + # 匹配所有以 /images/ 开头的表达式,如果匹配成功,则停止匹配查找,停止搜索。 + # 所以,即便有符合的正则表达式location,也不会被使用 + [ configuration D ] +} + +location ~* \.(gif|jpg|jpeg)$ { + # 匹配所有以 gif jpg jpeg结尾的请求。 + # 但是 以 /images/开头的请求,将使用 Configuration D,D具有更高的优先级 + [ configuration E ] +} + +location /images/ { + # 字符匹配到 /images/,还会继续往下搜索 + [ configuration F ] +} + + +location = /test.htm { + root /usr/local/var/www/htm; + index index.htm; +} +``` +注意:location的优先级与location配置的位置无关 + + +### 特定指令 + +1. return指令 +返回http状态码 和 可选的第二个参数可以是重定向的URL +``` +location /permanently/moved/url { + return 301 http://www.example.com/moved/here; +} +``` + +2. rewrite指令 +重写URI请求 rewrite,通过使用rewrite指令在请求处理期间多次修改请求URI,该指令具有一个可选参数和两个必需参数。 + * 第一个(必需)参数是请求URI必须匹配的正则表达式。 + * 第二个参数是用于替换匹配URI的URI。 + * 可选的第三个参数是可以停止进一步重写指令的处理或发送重定向(代码301或302)的标志 + +``` +location /users/ { + rewrite ^/users/(.*)$ /show?user=$1 break; +} +``` +1. error_page指令 +使用error_page指令,您可以配置NGINX返回自定义页面以及错误代码,替换响应中的其他错误代码,或将浏览器重定向到其他URI。在以下示例中,error_page指令指定要返回404页面错误代码的页面(/404.html)。 + +``` +error_page 404 /404.html; +``` + +4. log_format日志。 + 访问日志:需要开启压缩 gzip on; 否则不生成日志文件,打开log_format、access_log注释 + +``` +log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + +access_log /usr/local/etc/nginx/logs/host.access.log main; + +gzip on; +``` + +5. deny 指令 +``` +# 禁止访问某个目录 +location ~* \.(txt|doc)${ + root $doc_root; + deny all; +} +``` + +### 内置变量 +nginx的配置文件中可以使用的内置变量以美元符$开始,也有人叫全局变量。其中,部分预定义的变量的值是可以改变的。 + +- `$args` :#这个变量等于请求行中的参数,同$query_string +- `$content_length` :请求头中的Content-length字段。 +- `$content_type` :请求头中的Content-Type字段。 +- `$document_root` :当前请求在root指令中指定的值。 +- `$host` :请求主机头字段,否则为服务器名称。 +- `$http_user_agent` :客户端agent信息 +- `$http_cookie` :客户端cookie信息 +- `$limit_rate` :这个变量可以限制连接速率。 +- `$request_method` :客户端请求的动作,通常为GET或POST。 +- `$remote_addr` :客户端的IP地址。 +- `$remote_port` :客户端的端口。 +- `$remote_user` :已经经过Auth Basic Module验证的用户名。 +- `$request_filename` :当前请求的文件路径,由root或alias指令与URI请求生成。 +- `$scheme` :HTTP方法(如http,https)。 +- `$server_protocol` :请求使用的协议,通常是HTTP/1.0或HTTP/1.1。 +- `$server_addr` :服务器地址,在完成一次系统调用后可以确定这个值。 +- `$server_name `:服务器名称。 +- `$server_port` :请求到达服务器的端口号。 +- `$request_uri` :包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。 +- `$uri` :不带请求参数的当前URI,`$uri`不包含主机名,如”/foo/bar.html”。 +- `$document_uri` :与`$uri`相同 + +## 3. 反向代理 + +### 什么是反向代理 +反向代理(Reverse Proxy)方式是指以代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。 + +![alt text](image/image-1.png) + +### Http反向代理 +conf/nginx.conf 是 nginx 的默认配置文件。你也可以使用 nginx -c 指定你的配置文件。nginx.conf 配置文件如下 + +``` +#运行用户 +#user somebody; + +#启动进程,通常设置成和cpu的数量相等 +worker_processes 1; + +#全局错误日志 +error_log D:/Tools/nginx-1.10.1/logs/error.log; +error_log D:/Tools/nginx-1.10.1/logs/notice.log notice; +error_log D:/Tools/nginx-1.10.1/logs/info.log info; + +#PID文件,记录当前启动的nginx的进程ID +pid D:/Tools/nginx-1.10.1/logs/nginx.pid; + +#工作模式及连接数上限 +events { + worker_connections 1024; #单个后台worker process进程的最大并发链接数 +} + +#设定http服务器,利用它的反向代理功能提供负载均衡支持 +http { + #设定mime类型(邮件支持类型),类型由mime.types文件定义 + include D:/Tools/nginx-1.10.1/conf/mime.types; + default_type application/octet-stream; + + #设定日志 + log_format main '[$remote_addr] - [$remote_user] [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log D:/Tools/nginx-1.10.1/logs/access.log main; + rewrite_log on; + + #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用, + #必须设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,以平衡磁盘与网络I/O处理速度,降低系统的uptime. + sendfile on; + #tcp_nopush on; + + #连接超时时间 + keepalive_timeout 120; + tcp_nodelay on; + + #gzip压缩开关 + #gzip on; + + #设定实际的服务器列表 + upstream zp_server1{ + server 127.0.0.1:8089; + } + + #HTTP服务器 + server { + #监听80端口,80端口是知名端口号,用于HTTP协议 + listen 80; + + #定义使用www.xx.com访问 + server_name www.helloworld.com; + + #首页 + index index.html + + #指向webapp的目录 + root D:\01_Workspace\Project\github\zp\SpringNotes\spring-security\spring-shiro\src\main\webapp; + + #编码格式 + charset utf-8; + + #代理配置参数 + proxy_connect_timeout 180; + proxy_send_timeout 180; + proxy_read_timeout 180; + proxy_set_header Host $host; + proxy_set_header X-Forwarder-For $remote_addr; + + #反向代理的路径(和upstream绑定),location 后面设置映射的路径 + location / { + proxy_pass http://zp_server1; + } + + #静态文件,nginx自己处理 + location ~ ^/(images|javascript|js|css|flash|media|static)/ { + root D:\01_Workspace\Project\github\zp\SpringNotes\spring-security\spring-shiro\src\main\webapp\views; + #过期30天,静态文件不怎么更新,过期可以设大一点,如果频繁更新,则可以设置得小一点。 + expires 30d; + } + + #设定查看Nginx状态的地址 + location /NginxStatus { + stub_status on; + access_log on; + auth_basic "NginxStatus"; + auth_basic_user_file conf/htpasswd; + } + + #禁止访问 .htxxx 文件 + location ~ /\.ht { + deny all; + } + + #错误处理页面(可选择性配置) + #error_page 404 /404.html; + #error_page 500 502 503 504 /50x.html; + #location = /50x.html { + # root html; + #} + } +} +``` + +启动调试 + +1. 启动 webapp,注意启动绑定的端口要和 nginx 中的 upstream 设置的端口保持一致。 +2. 更改 host:在 C:\Windows\System32\drivers\etc 目录下的 host 文件中添加一条 DNS 记录 +``` +127.0.0.1 www.helloworld.com +``` +3. 启动前文中 startup.bat 的命令 +4. 在浏览器中访问 www.helloworld.com,不出意外,已经可以访问了。 + +### Https反向代理 + +一些对安全性要求比较高的站点,可能会使用 HTTPS(一种使用 ssl 通信标准的安全 HTTP 协议)。 + +这里不科普 HTTP 协议和 SSL 标准。但是,使用 nginx 配置 https 需要知道几点: + +* HTTPS 的固定端口号是 443,不同于 HTTP 的 80 端口 +* SSL 标准需要引入安全证书,所以在 nginx.conf 中你需要指定证书和它对应的 key +其他和 http 反向代理基本一样,只是在 Server 部分配置有些不同。 +``` + #HTTP服务器 + server { + #监听443端口。443为知名端口号,主要用于HTTPS协议 + listen 443 ssl; + + #定义使用www.xx.com访问 + server_name www.helloworld.com; + + #ssl证书文件位置(常见证书文件格式为:crt/pem) + ssl_certificate cert.pem; + #ssl证书key位置 + ssl_certificate_key cert.key; + + #ssl配置参数(选择性配置) + ssl_session_cache shared:SSL:1m; + ssl_session_timeout 5m; + #数字签名,此处使用MD5 + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + + location / { + root /root; + index index.html index.htm; + } + } +``` + +## 4. 负载均衡 + +### 什么是负载均衡 + +前面的例子中,代理仅仅指向一个服务器。 + +但是,网站在实际运营过程中,大部分都是以集群的方式运行,这时需要使用负载均衡来分流。 + +nginx 也可以实现简单的负载均衡功能。 + +![alt text](image/image-2.png) + + +### Nginx配置 +假设这样一个应用场景:将应用部署在 192.168.1.11:80、192.168.1.12:80、192.168.1.13:80 三台 linux 环境的服务器上。网站域名叫 www.helloworld.com,公网 IP 为 192.168.1.11。在公网 IP 所在的服务器上部署 nginx,对所有请求做负载均衡处理(下面例子中使用的是加权轮询策略)。 + +nginx.conf 配置如下: + +``` +http { + #设定mime类型,类型由mime.type文件定义 + include /etc/nginx/mime.types; + default_type application/octet-stream; + #设定日志格式 + access_log /var/log/nginx/access.log; + + #设定负载均衡的服务器列表 + upstream load_balance_server { + #weigth参数表示权值,权值越高被分配到的几率越大 + server 192.168.1.11:80 weight=5; + server 192.168.1.12:80 weight=1; + server 192.168.1.13:80 weight=6; + } + + #HTTP服务器 + server { + #侦听80端口 + listen 80; + + #定义使用www.xx.com访问 + server_name www.helloworld.com; + + #对所有请求进行负载均衡请求 + location / { + root /root; #定义服务器的默认网站根目录位置 + index index.html index.htm; #定义首页索引文件的名称 + proxy_pass http://load_balance_server ;#请求转向load_balance_server 定义的服务器列表 + + #以下是一些反向代理的配置(可选择性配置) + #proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP + proxy_set_header X-Forwarded-For $remote_addr; + proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时) + proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时) + proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时) + proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小 + proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置 + proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2) + proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传 + + client_max_body_size 10m; #允许客户端请求的最大单文件字节数 + client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数 + } + } +} +``` + +### 负载均衡策略 + +Nginx 提供了多种负载均衡策略,负载均衡策略在各种分布式系统中基本上原理一致 + +### 轮询 +``` +upstream bck_testing_01 { + # 默认所有服务器权重为 1 + server 192.168.250.220:8080 + server 192.168.250.221:8080 + server 192.168.250.222:8080 +} +``` +### 加权轮询 +``` +upstream bck_testing_01 { + server 192.168.250.220:8080 weight=3 + server 192.168.250.221:8080 # default weight=1 + server 192.168.250.222:8080 # default weight=1 +} +``` +### 最少连接 +``` +upstream bck_testing_01 { + least_conn; + + # with default weight for all (weight=1) + server 192.168.250.220:8080 + server 192.168.250.221:8080 + server 192.168.250.222:8080 +} +``` +### 加权最少连接 +``` +upstream bck_testing_01 { + least_conn; + + server 192.168.250.220:8080 weight=3 + server 192.168.250.221:8080 # default weight=1 + server 192.168.250.222:8080 # default weight=1 +} +``` +### IP Hash +``` +upstream bck_testing_01 { + + ip_hash; + + # with default weight for all (weight=1) + server 192.168.250.220:8080 + server 192.168.250.221:8080 + server 192.168.250.222:8080 + +} +``` +#### 普通 Hash +``` +upstream bck_testing_01 { + + hash $request_uri; + + # with default weight for all (weight=1) + server 192.168.250.220:8080 + server 192.168.250.221:8080 + server 192.168.250.222:8080 + +} +``` + +## 5. 网络转发 + +### 什么是网络转发 + +当一个网站功能越来越丰富时,往往需要将一些功能相对独立的模块剥离出来,独立维护。这样的话,通常,会有多个 webapp。 + +举个例子:假如 www.helloworld.com 站点有好几个 webapp,finance(金融)、product(产品)、admin(用户中心)。访问这些应用的方式通过上下文(context)来进行区分: + +www.helloworld.com/finance/ + +www.helloworld.com/product/ + +www.helloworld.com/admin/ + +我们知道,http 的默认端口号是 80,如果在一台服务器上同时启动这 3 个 webapp 应用,都用 80 端口,肯定是不成的。所以,这三个应用需要分别绑定不同的端口号。 + +那么,问题来了,用户在实际访问 www.helloworld.com 站点时,访问不同 webapp,总不会还带着对应的端口号去访问吧。所以,你再次需要用到反向代理来做处理。 + +### Nginx配置 + +``` +http { + #此处省略一些基本配置 + + upstream product_server{ + server www.helloworld.com:8081; + } + + upstream admin_server{ + server www.helloworld.com:8082; + } + + upstream finance_server{ + server www.helloworld.com:8083; + } + + server { + #此处省略一些基本配置 + #默认指向product的server + location / { + proxy_pass http://product_server; + } + + location /product/{ + proxy_pass http://product_server; + } + + location /admin/ { + proxy_pass http://admin_server; + } + + location /finance/ { + proxy_pass http://finance_server; + } + } +} +``` + +## 6. 静态站点 + +### 什么是静态站带你 +我们需要配置静态站点(即 html 文件和一堆静态资源)。 + + +### Nginx配置 +举例来说:如果所有的静态资源都放在了 /app/dist 目录下,我们只需要在 nginx.conf 中指定首页以及这个站点的 host 即可。 + +配置如下: +``` +worker_processes 1; + +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + sendfile on; + keepalive_timeout 65; + + gzip on; + gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/javascript image/jpeg image/gif image/png; + gzip_vary on; + + server { + listen 80; + server_name static.zp.cn; + + location / { + root /app/dist; + index index.html; + #转发任何请求到 index.html + } + } +} +``` +然后,添加 HOST: +``` +127.0.0.1 static.zp.cn +``` +此时,在本地浏览器访问 static.zp.cn ,就可以访问静态站点了。 \ No newline at end of file diff --git a/Nginx/image/image-1.png b/Nginx/image/image-1.png new file mode 100644 index 00000000..e58f945d Binary files /dev/null and b/Nginx/image/image-1.png differ diff --git a/Nginx/image/image-2.png b/Nginx/image/image-2.png new file mode 100644 index 00000000..26b3b0aa Binary files /dev/null and b/Nginx/image/image-2.png differ diff --git a/Nginx/image/image.png b/Nginx/image/image.png new file mode 100644 index 00000000..f0dc579b Binary files /dev/null and b/Nginx/image/image.png differ diff --git a/基金股票/01 基金基础知识.md b/基金股票/01 基金基础知识.md new file mode 100644 index 00000000..19ccafe4 --- /dev/null +++ b/基金股票/01 基金基础知识.md @@ -0,0 +1,11 @@ + + + +## 基金的分类方式 + + +### 按照投资对象分类 + +* 股票基金:主要投资与股票,股票投资占基金资产的比例通常在80%以上,这类基金的收益与股票市场的表现密切相关,风险较高,但潜在收益也高。 +* 债券基金:主要投资债券 +