diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..bc36a8e5 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,25 @@ +# http://editorconfig.org +# 官网首页有介绍:IntelliJ IDEA,VS Code 默认就支持,无需额外安装插件 +root = true + +# 空格替代Tab缩进在各种编辑工具下效果一致 +[*] +indent_style = space +indent_size = 4 +charset = utf-8 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true +max_line_length = 200 + + + +[*.java] +indent_style = tab + +[*.{json,yml}] +indent_size = 2 + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..2cbbc96c --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +build/ +out/ +log/ +logs/ +public/ +target/ +node_modules/ +classes/ +.deploy*/ +.gradle +*.log.* +*.log +.DS_Store +Thumbs.db + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ \ No newline at end of file diff --git a/CentOS-7-Install.md b/CentOS-7-Install.md deleted file mode 100644 index 3f2aec9d..00000000 --- a/CentOS-7-Install.md +++ /dev/null @@ -1,43 +0,0 @@ -# CentOS 安装 - - -## 概括 - -- 本教程中主要演示了 VMware Workstation 下安装 `CentOS 7.3` 的过程。 -- VMware 的使用细节可以看这篇:[CentOS 6 安装](CentOS-Install.md) - -## VMware 下安装 CentOS 过程 - -- VMware Workstation 的介绍和下载 - - 官网: - - wiki: - - 百度 wiki: - - 百度云下载(64 位): - - 官网下载: - - -- 安装细节开始: - - ![VMware 下安装](images/CentOS-7-Install-a-1.jpg) - - ![VMware 下安装](images/CentOS-7-Install-a-2.jpg) - - ![VMware 下安装](images/CentOS-7-Install-a-3.jpg) - - ![VMware 下安装](images/CentOS-7-Install-a-4.jpg) - - ![VMware 下安装](images/CentOS-7-Install-a-5.jpg) - - 如上图,默认是最小安装,点击进去,选择桌面安装。 - - 如上图,默认是自动分区,如果懂得分区,点击进去,进行手动分区,CentOS 7 少了主分区,逻辑分区的选择了。 - - ![VMware 下安装](images/CentOS-7-Install-a-6.jpg) - - 如上图,root 密码必须设置,我习惯测试的时候是:123456 - - 我没有创建用户,喜欢用 root - - ![VMware 下安装](images/CentOS-7-Install-a-7.jpg) - - ![VMware 下安装](images/CentOS-7-Install-a-8.jpg) - - 如上图,许可证必须点击进去勾选同意相关协议。 - - 如上图,网络可以稍后在设置,主机名可以现在先填写 - - ![VMware 下安装](images/CentOS-7-Install-a-9.jpg) - - ![VMware 下安装](images/CentOS-7-Install-a-10.jpg) - - ![VMware 下安装](images/CentOS-7-Install-a-11.jpg) - - ![VMware 下安装](images/CentOS-7-Install-a-12.jpg) - - 如上图右上角,一般我们都选择跳过 - - ![VMware 下安装](images/CentOS-7-Install-a-13.jpg) - - ![VMware 下安装](images/CentOS-7-Install-a-14.jpg) - - ![VMware 下安装](images/CentOS-7-Install-a-15.jpg) - - ![VMware 下安装](images/CentOS-7-Install-a-16.jpg) - - 到此完成,其他该做啥就做啥 \ No newline at end of file diff --git a/CentOS-Install.md b/CentOS-Install.md deleted file mode 100644 index 4982a38d..00000000 --- a/CentOS-Install.md +++ /dev/null @@ -1,116 +0,0 @@ -# CentOS 安装 - - -## 概括 - -- 本教程中主要演示了 VirtualBox 和 VMware Workstation 下安装 `CentOS 6.6` 的过程。 -- VirtualBox 是免费开源,我个人在使用经历中遇到过很多次崩溃、安装有问题等,所以它不是我主推的虚拟机 -- VMware Workstation 是商业软件,很好用,一些辅助功能也很到位,主推该虚拟机。 - - -## VirtualBox 下安装 CentOS 过程 - -- VirtualBox 的介绍和下载 - - 官网: - - wiki: - - 百度 wiki: - - 百度云下载(32 位和 64 位一体): - - 官网下载: - - -- 安装细节开始: - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-1.jpg) - - 如上图标注 1 所示:点击 `新建` 一个虚拟机。 - - 如上图标注 2 所示:在填写 `名称` 的时候,输入 `CentOS` 相关字眼的时候,下面的版本类型会跟着变化,自动识别为 `Red Hat` - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-2.jpg) - - 如上图标注 1 所示:我们装的是 64 位系统,如果你本机内存足够大,建议可以给 2 ~ 4 G 的容量 - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-3.jpg) - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-4.jpg) - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-5.jpg) - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-6.jpg) - - 如上图所示,命名最好规范,最好要带上系统版本号,硬盘大小建议在 8 ~ 20 G - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-b-1.gif) - - 如上图 gif 演示,当我们创建好虚拟机之后,需要选择模拟光驱进行系统镜像安装 - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-7.jpg) - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-8.jpg) - - 如上图箭头所示,我们这里选择 `Skip`,跳过对镜像的检查,这个一般需要检查很久,而且我们用 iso 文件安装的,一般没这个必要 - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-9.jpg) - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-12.jpg) - - 如上图标注 1 所示,建议 Linux 纯新手使用简体中文环境 - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-13.jpg) - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-14.jpg) - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-15.jpg) - - 如上图标注 1 所示,因为我们是用全新的虚拟机,虚拟出来的硬盘都是空的,所以这里可以忽略所有数据 - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-16.jpg) - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-17.jpg) - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-18.jpg) - - 再次强调下,root 账号也就是图上所说的 `根账号`,它是最顶级账号,密码最好别忘记了 - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-19.jpg) - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-20.jpg) - - 如上图标注 1 所示,因为我们是用全新的虚拟机,所以这里选择 `使用所有空间` ,然后 CentOS 会按它默认的方式进行分区 - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-21.jpg) - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-22.jpg) - - `Desktop` 代表:图形界面版,会默认安装很多软件,建议新手选择此模式,我后面其他文章的讲解都是基于此系统下,如果你不是此模式的系统可能在安装某些软件的时候会出现某些依赖包没有安装的情况 - - `basic sever` 代表:命令行界面,有良好基础的基本都会喜欢这个 - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-23.jpg) - - 上一步我选择的是 `Desktop` 所以有很多软件需要安装,这个过程大概需要 5 ~ 10 分钟 - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-24.jpg) - - 安装完成 - - ![VirtualBox 下安装](images/CentOS-Install-VirtualBox-a-25.jpg) - - 安装完成后一定要把盘片删除,防止系统启动的时候去读盘,重新进入安装系统模式 - - -## VMware 下安装 CentOS 过程 - -- VMware Workstation 的介绍和下载 - - 官网: - - wiki: - - 百度 wiki: - - 百度云下载(64 位): - - 官网下载: - - -- 安装细节开始: - - ![VMware 下安装](images/CentOS-install-VMware-a-1.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-a-2.jpg) - - 默认 VMware 选择的是 `典型` 我不推荐,我下面的步骤是选择 `自定义(高级)`。如果你非常了解 Linux 系统倒是可以考虑选择 `典型`,在它默认安装完的系统上可以很好地按你的需求进行修改 - - ![VMware 下安装](images/CentOS-install-VMware-a-3.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-a-4.jpg) - - 牢记:不要在这一步就选择镜像文件,不然也会直接进入 `典型` 模式,直接按它的规则进行系统安装 - - ![VMware 下安装](images/CentOS-install-VMware-a-5.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-a-6.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-a-7.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-a-8.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-a-9.jpg) - - 桥接模式:(建议选择此模式)创建一个独立的虚拟主机,在桥接模式下的虚拟主机网络一般要为其配 IP 地址、子网掩码、默认网关(虚拟机ip地址要与主机ip地址处于同网段) - - NAT 模式:把物理主机作为路由器进行访问互联网,优势:联网简单,劣势:虚拟主机无法与物理主机通讯 - - 主机模式:把虚拟主机网络与真实网络隔开,但是各个虚拟机之间可以互相连接,虚拟机和物理机也可以连接 - - > 上面解释来源: - - ![VMware 下安装](images/CentOS-install-VMware-a-10.jpg) - - Buslogic 和 LSIlogic 都是虚拟硬盘 SCSI 设备的类型,旧版本的 OS 默认的是 Buslogic,LSIlogic 类型的硬盘改进了性能,对于小文件的读取速度有提高,支持非 SCSI 硬盘比较好。 - - > 上面解释来源: - - ![VMware 下安装](images/CentOS-install-VMware-a-11.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-a-12.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-a-13.jpg) - - 强烈建议至少要给 20 G,不然装不了多少软件的 - - ![VMware 下安装](images/CentOS-install-VMware-a-14.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-a-15.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-b-1.gif) - - 如上图 gif 所示,在创建完虚拟机之后,我们要加载系统镜像,然后启动虚拟机进行安装,接下来的安装步骤跟上面使用 VirtualBox 安装细节基本一样,不一样的地方是我这里选择的是自定义分区,不再是选择默认分区方式 - - ![VMware 下安装](images/CentOS-install-VMware-a-16.jpg) - - 如上图箭头所示,这里我们选择自定义分区方式 - - ![VMware 下安装](images/CentOS-install-VMware-b-2.gif) - - 如上图 gif 所示,我只把最基本的区分出来,如果你有自己的需求可以自己设置 - - 简单分区方案: - - `/boot` == 500 M(主分区) - - `/swap` == 2 G(逻辑分区)一般大家的说法这个大小是跟你机子的内存大小相关的,也有说法内存大不需要这个,但是还是建议分,虚拟机内存 2 G,所以我分 2 G - - `/` == 剩余容量(逻辑分区)剩余的空间都给了根分区 - - ![VMware 下安装](images/CentOS-install-VMware-a-17.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-a-18.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-a-19.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-a-20.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-a-21.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-a-22.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-a-23.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-a-24.jpg) - - ![VMware 下安装](images/CentOS-install-VMware-a-25.jpg) diff --git a/Crontab.md b/Crontab.md deleted file mode 100644 index 0eba3f5e..00000000 --- a/Crontab.md +++ /dev/null @@ -1,33 +0,0 @@ -# Crontab 介绍 - - -## Crontab 安装 - -- 查看是否已安装: - - CentOS:`rpm -qa | grep cron` - - Ubuntu:`dpkg -l | grep cron` - -- 安装(一般系统是集成的): - - CentOS 6:`sudo yum install -y vixie-cron crontabs` - - Ubuntu:`sudo apt-get install -y cron` - -## Crontab 服务器配置文件常用参数 - -- 配置文件介绍(记得先备份):`sudo vim /etc/crontab` - - 该配置格式解释: - - ![Crontab 服务器配置文件常用参数](images/Crontab-a-1.jpg) - - 常用例子介绍: - - 30 21 * * * service httpd restart #每晚的 21:30 重启 apache - - 45 4 1,10,22 * * service httpd restart #每月的 1、10、22 日的 4:45 重启 apache - - 45 4 1-10 * * service httpd restart #每月的 1 到 10 日的 4:45 重启 apache - - */2 * * * * service httpd restart #每隔两分钟重启 apache - - 1-59/2 * * * * service httpd restart #每隔两分钟重启 apache(这个比较特殊:1-59/2 这个表示过掉0分,从 1 分开始算,每隔两分执行,所以 1 分执行了,3 分执行了,5 分执行了....都是奇数进行执行。默认的 */2 都是偶数执行。) - - 0 23-7/2 * * * service httpd restart #晚上 11 点到早上 7 点之间,每隔 2 个小时重启 apache - - 0-59/30 18-23 * * * service httpd restart #每天 18:00 到 23:00 之间,每隔 30 分钟重启 apache(方法一) - - 0,30 18-23 * * * service httpd restart #每天 18:00 到 23:00 之间,每隔 30 分钟重启 apache(方法二) -- 执行记录日志:`cd /var/log/cron` - -## Crontab 资料 - -- -- diff --git a/Docker-Install-And-Usage.md b/Docker-Install-And-Usage.md deleted file mode 100644 index 93de6260..00000000 --- a/Docker-Install-And-Usage.md +++ /dev/null @@ -1,809 +0,0 @@ - - -# Docker 使用 - -## 环境说明 - -- CentOS 7.3(不准确地说:要求必须是 CentOS 7 64位) -- 不建议在 Windows 上使用 - -## Docker 基本概念 - -- 官网: -- 宿主机:安装 Docker 的那台电脑 -- Docker:一个虚拟化软件,你可以认为是类似:VMware、Virtualbox -- 镜像:可以认为是类似 Windows 下的:XXXX.iso -- 容器:容器为镜像的实例,可以认为是 Virtualbox 运行 XXXX.iso 后的效果 -- 官网的镜像仓库地址: -- 对开发来讲总结一个最简单的说法:在 Maven 未产生的年代,jar 包要随着开发项目走到哪里跟到哪里。有了 Maven 写好 pom.xml 即可。此时的 Docker 就好比如 Maven,帮你省去了开发过程中的部署环境差异,你再也不能随便说:你的系统可以运行,我的系统就不行。现在别人连系统都帮你做好了。 -- 玩法理念:单进程,一个容器最好最专注去做一个事情。虽然它可以既装 MySQL,又装 Nginx 等等,但是让一个容器只做好一件事是最合适的。 -- 其他通俗解释: - -> Docker的思想来自于集装箱,集装箱解决了什么问题?在一艘大船上,可以把货物规整的摆放起来。并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响。那么我就不需要专门运送水果的船和专门运送化学品的船了。只要这些货物在集装箱里封装的好好的,那我就可以用一艘大船把他们都运走。 - docker就是类似的理念。现在都流行云计算了,云计算就好比大货轮。docker就是集装箱。 - 1.不同的应用程序可能会有不同的应用环境,比如.net开发的网站和php开发的网站依赖的软件就不一样,如果把他们依赖的软件都安装在一个服务器上就要调试很久,而且很麻烦,还会造成一些冲突。比如IIS和Apache访问端口冲突。这个时候你就要隔离.net开发的网站和php开发的网站。常规来讲,我们可以在服务器上创建不同的虚拟机在不同的虚拟机上放置不同的应用,但是虚拟机开销比较高。docker可以实现虚拟机隔离应用环境的功能,并且开销比虚拟机小,小就意味着省钱了。 - 2.你开发软件的时候用的是Ubuntu,但是运维管理的都是centos,运维在把你的软件从开发环境转移到生产环境的时候就会遇到一些Ubuntu转centos的问题,比如:有个特殊版本的数据库,只有Ubuntu支持,centos不支持,在转移的过程当中运维就得想办法解决这样的问题。这时候要是有docker你就可以把开发环境直接封装转移给运维,运维直接部署你给他的docker就可以了。而且部署速度快。 - 3.在服务器负载方面,如果你单独开一个虚拟机,那么虚拟机会占用空闲内存的,docker部署的话,这些内存就会利用起来。 - 总之docker就是集装箱原理。 - -- Docker 的优点: -- 持续部署与测试 - -> Docker在开发与运维的世界中具有极大的吸引力,因为它能保持跨环境的一致性。在开发与发布的生命周期中,不同的环境具有细微的不同,这些差异可能是由于不同安装包的版本和依赖关系引起的。然而,Docker可以通过确保从开发到产品发布整个过程环境的一致性来解决这个问题。 - Docker容器通过相关配置,保持容器内部所有的配置和依赖关系始终不变。最终,你可以在开发到产品发布的整个过程中使用相同的容器来确保没有任何差异或者人工干预。 - 使用Docker,你还可以确保开发者不需要配置完全相同的产品环境,他们可以在他们自己的系统上通过VirtualBox建立虚拟机来运行Docker容器。Docker的魅力在于它同样可以让你在亚马逊EC2实例上运行相同的容器。如果你需要在一个产品发布周期中完成一次升级,你可以很容易地将需要变更的东西放到Docker容器中,测试它们,并且使你已经存在的容器执行相同的变更。这种灵活性就是使用Docker的一个主要好处。和标准部署与集成过程一样,Docker可以让你构建、测试和发布镜像,这个镜像可以跨多个服务器进行部署。哪怕安装一个新的安全补丁,整个过程也是一样的。你可以安装补丁,然后测试它,并且将这个补丁发布到产品中。 - -- 环境标准化和版本控制 - -> Docker容器可以在不同的开发与产品发布生命周期中确保一致性,进而标准化你的环境。除此之外,Docker容器还可以像git仓库一样,可以让你提交变更到Docker镜像中并通过不同的版本来管理它们。设想如果你因为完成了一个组件的升级而导致你整个环境都损坏了,Docker可以让你轻松地回滚到这个镜像的前一个版本。这整个过程可以在几分钟内完成,如果和虚拟机的备份或者镜像创建流程对比,那Docker算相当快的,它可以让你快速地进行复制和实现冗余。此外,启动Docker就和运行一个进程一样快。 - -- 隔离性 - -> Docker可以确保你的应用程序与资源是分隔开的。几个月前,Gartner发表了一篇报告,这份报告说明了运行Docker 容器进行资源隔离的效果和虚拟机(VM)管理程序一样的好,但是管理与控制方面还需要进行完善。我们考虑这样一个场景,你在你的虚拟机中运行了很多应用程序,这些应用程序包括团队协作软件(例如Confluence)、问题追踪软件(例如JIRA)、集中身份管理系统(例如Crowd)等等。由于这些软件运行在不同的端口上,所以你必须使用Apache或者Nginx来做反向代理。到目前为止,一切都很正常,但是随着你的环境向前推进,你需要在你现有的环境中配置一个内容管理系统(例如Alfresco)。这时候有个问题发生了,这个软件需要一个不同版本的Apache Tomcat,为了满足这个需求,你只能将你现有的软件迁移到另一个版本的Tomcat上,或者找到适合你现有Tomcat的内容管理系统(Alfresco)版本。对于上述场景,使用Docker就不用做这些事情了。Docker能够确保每个容器都拥有自己的资源,并且和其他容器是隔离的。你可以用不同的容器来运行使用不同堆栈的应用程序。除此之外,如果你想在服务器上直接删除一些应用程序是比较困难的,因为这样可能引发依赖关系冲突。而Docker可以帮你确保应用程序被完全清除,因为不同的应用程序运行在不同的容器上,如果你不在需要一款应用程序,那你可以简单地通过删除容器来删除这个应用程序,并且在你的宿主机操作系统上不会留下任何的临时文件或者配置文件。除了上述好处,Docker还能确保每个应用程序只使用分配给它的资源(包括CPU、内存和磁盘空间)。一个特殊的软件将不会使用你全部的可用资源,要不然这将导致性能降低,甚至让其他应用程序完全停止工作。 - -- 安全性 - -> 如上所述,Gartner也承认Docker正在快速地发展。从安全角度来看,Docker确保运行在容器中的应用程序和其他容器中的应用程序是完全分隔与隔离的,在通信流量和管理上赋予你完全的控制权。Docker容器不能窥视运行在其他容器中的进程。从体系结构角度来看,每个容器只使用着自己的资源(从进程到网络堆栈)。作为紧固安全的一种手段,Docker将宿主机操作系统上的敏感挂载点(例如/proc和/sys)作为只读挂载点,并且使用一种写时复制系统来确保容器不能读取其他容器的数据。Docker也限制了宿主机操作系统上的一些系统调用,并且和SELinux与AppArmor一起运行的很好。此外,在Docker Hub上可以使用的Docker镜像都通过数字签名来确保其可靠性。由于Docker容器是隔离的,并且资源是受限制的,所以即使你其中一个应用程序被黑,也不会影响运行在其它Docker容器上的应用程序。 - -- 多云平台 - -> Docker最大的好处之一就是可移植性。在过去的几年里,所有主流的云计算提供商,包括亚马逊AWS和谷歌的GCP,都将Docker融入到他们的平台并增加了各自的支持。Docker容器能运行在亚马逊的EC2实例、谷歌的GCP实例、Rackspace服务器或者VirtualBox这些提供主机操作系统的平台上。举例来说,如果运行在亚马逊EC2实例上的Docker容器能够很容易地移植到其他几个平台上,比如说VirtualBox,并且达到类似的一致性和功能性,那这将允许你从基础设施层中抽象出来。除了AWS和GCP,Docker在其他不同的IaaS提供商也运行的非常好,例如微软的Azure、OpenStack和可以被具有不同配置的管理者所使用的Chef、Puppet、Ansible等。 - - - -## Docker 安装和基本配置 - -- 主要有两个版本: - -> **Docker Enterprise Edition (Docker EE)** is designed for enterprise development and IT teams who build, ship, and run business critical applications in production at scale. Docker EE is integrated, certified, and supported to provide enterprises with the most secure container platform in the industry to modernize all applications. For more information about Docker EE, including purchasing options, see Docker Enterprise Edition. -**Docker Community Edition (Docker CE)** is ideal for developers and small teams looking to get started with Docker and experimenting with container-based apps. Docker CE is available on many platforms, from desktop to cloud to server. Docker CE is available for macOS and Windows and provides a native experience to help you focus on learning Docker. You can build and share containers and automate the development pipeline all from a single environment. -Docker CE has both stable and edge channels. - Stable builds are released once per quarter and are supported for 4 months. - Edge builds are released once per month, and are supported for that month only. If you subscribe to the Edge channel on Linux distributions, you should also subscribe to the Stable channel. - - -- 官网总的安装手册: -- 官网 CentOS 安装手册: -- 目前也支持 Windows,特别是 Windows 10,直接官网一个安装包即可搞定。 -- Windows 10 的 Docker 安装说明: -- 我这里选择 Docker CE 版本: -- CentOS 安装过程: - - `sudo yum install -y yum-utils device-mapper-persistent-data lvm2` - - 添加 repo(可能网络会很慢,有时候会报:Timeout,所以要多试几次) - - `sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo` - - `sudo yum makecache fast` - - `sudo yum install -y docker-ce`,大小:19M,速度很慢。 -- 启动 Docker:`systemctl start docker.service` -- 停止 Docker:`systemctl stop docker.service` -- 查看状态:`systemctl status docker.service` -- 运行 hello world 镜像:`sudo docker run hello-world` - - 因为是第一次使用,所以没这个镜像,需要一个下载过程,所以需要几分钟,可能还会报:Timeout。 - - 镜像自动下载好后会输出这样一段内容,表示已经正常安装并可用了: - - ``` bash - Unable to find image 'hello-world:latest' locally - latest: Pulling from library/hello-world - 78445dd45222: Pull complete - Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7 - Status: Downloaded newer image for hello-world:latest - - Hello from Docker! - This message shows that your installation appears to be working correctly. - - To generate this message, Docker took the following steps: - 1. The Docker client contacted the Docker daemon. - 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. - 3. The Docker daemon created a new container from that image which runs the - executable that produces the output you are currently reading. - 4. The Docker daemon streamed that output to the Docker client, which sent it - to your terminal. - - To try something more ambitious, you can run an Ubuntu container with: - $ docker run -it ubuntu bash - - Share images, automate workflows, and more with a free Docker ID: - https://cloud.docker.com/ - - For more examples and ideas, visit: - https://docs.docker.com/engine/userguide/ - ``` - - -## 镜像加速 - -- 只要是外国的东西在国内基本都很难有好的速度,所有就有了加速器的概念,目前国内常用的如下: -- 阿里云: -- USTC: -- daocloud: -- 网易: -- 时速云: -- 灵雀云: -- 推荐优先阿里云,然后是 USTC -- 我下面的讲解也是基于阿里云加速 -- 阿里云的服务需要注册账号,**首次使用需要设置 docker 登录密码,这个以后用私人仓库会用到。** - - 注册后请访问:,你会看到专属的加速地址,比如我是:`https://ldhc17y9.mirror.aliyuncs.com`,所以下面文章你看到该地址都表示是这个专属地址,请记得自己更换自己的。 - - 以及教你如何使用 Docker 加速器。如果你已经安装了最新版的 Docker 你就不需要用它的脚本进行安装了。 -- 最新版本的 Docker 是新增配置文件:`vim /etc/docker/daemon.json`,增加如下内容: - -``` bash -{ - "registry-mirrors": ["https://ldhc17y9.mirror.aliyuncs.com"] -} -``` - -- `sudo systemctl daemon-reload` -- `sudo systemctl restart docker` -- 在以后的生活中如果要经常使用阿里云做为自己仓库,那你还需要做: - - 在 ` namespace管理` 中创建属于你自己的 namespace: - - 创建镜像仓库: - - 创建好仓库后,点击:`管理` 进入查看仓库的更多详细信息,这里面有很多有用的信息,包括一个详细的操作指南,**这份指南等下会用到。** - - 比如我自己创建的仓库,地址是阿里云给我们的:`registry.cn-shenzhen.aliyuncs.com/youmeek/open-hub` - -# Docker 命令,最终部署 Spring Boot 项目 - -- 建议:初期使用的时候尽量用容器 ID / 镜像 ID。如果使用 Tag/Name 在东西多的情况下很容易混乱 还不如就用记不住但是肯定唯一的容器 ID / 镜像 ID - -## 重要的基本概念 - -- 可以代表一个完整的镜像名有两种方式: - - REPOSITORY(仓库):TAG(标签) - - 其中 TAG 表面上不是必须有的,本质是 docker 帮你用 latest 来代替了。latest 这里最好翻译为默认,而不是最新。 - - IMAGE ID(镜像ID) - - 这是一个 Docker 随机给你生成 数字+字母 的字符串 - -## 部署一个 Spring Boot 的 Java Web 项目为例 - -- 宿主机环境说明: - - IP 地址:`http://192.168.137.128` - - 停止了防火墙:`systemctl stop firewalld.service ; systemctl stop iptables.service` - - 停止防火墙后重启 Docker 服务:`systemctl restart docker.service` - - JDK(jdk-8u121-linux-x64.tar.gz)、jar 应用(spring-boot-my-demo.jar),存放宿主机位置:`/opt/setups` - - Spring Boot 的 jar 应用中配置文件给的端口是:8080,常规情况下的访问路径:`http://127.0.0.1:8080/youmeek` -- 下载镜像:`docker pull centos:6.8`,我的 IMAGE_ID 为:`0cd976dc0a98` -- 运行镜像,实例化为一个容器:`docker run -i -t -v /opt/setups:/opt 0cd976dc0a98 /bin/bash` - - `-v:表示需要将本地宿主机的目录挂载到容器中对应的一个目录上,格式:-v <宿主机目录>:<容器目录>,所以此时对容器此目录的操作,也是等同于对宿主机的目录的操作` -- 在容器里安装 Oracle JDK 8、配置 JDK 环境变量这里不多说,具体看:[JDK 安装](https://github.com/judasn/Linux-Tutorial/blob/master/JDK-Install.md)。 -- 把容器中 /opt 目录下的 spring-boot-my-demo.jar 拷贝到容器的 root 目录下:`cp /opt/spring-boot-my-demo.jar /root` -- 再容器里新建脚本:`vi /root/spring-boot-run.sh`,脚本内容如下: - -``` bash -#!/bin/bash -source /etc/profile -java -jar /root/spring-boot-my-demo.jar -``` - -- 在容器中对新建脚本增加执行权限:`chmod u+x /root/spring-boot-run.sh` -- 我们启动另外一个终端 -- 查看我们刚刚运行的容器相关信息:`docker ps -a` - - 我们看到了我们刚刚运行的容器 ID(CONTAINER ID)为:`a5d544d9b6f9`,这个下面要用到 -- 基于刚刚运行的容器创建新镜像:`docker commit a5d544d9b6f9 youmeek/springboot:0.1` - - 查看现在的镜像库:`docker images`,会发现多了一个 youmeek/springboot 新镜像,镜像 ID 为:`7024f230fef9` -- 运行新镜像,实例化为一个容器,并启动容器中刚刚写的脚本:`docker run -d -p 38080:8080 --name springBootJar 7024f230fef9 /root/spring-boot-run.sh` - - `-d`:表示以“守护模式”执行 spring-boot-run.sh 脚本,此时 jar 中的 log 日志不会出现在输出终端上。 - - `-p`:表示宿主机与容器的端口映射,此时将容器内部的 8080 端口映射为宿主机的 38080 端口,这样就向外界暴露了 38080 端口,可通过 Docker 网桥来访问容器内部的 8080 端口了。 - - `--name`:表示给新实例容器取的名称,用一个有意义的名称命名即可 -- 查看其实运行的容器:`docker ps -a`,可以知道我们的新容器 ID:`fd21ac056343`,名称为:`springBootJar` -- 查看这个容器的 jar 应用的 log 输出:`docker logs -f fd21ac056343`,可以看到 jar 启动后的 log 输出内容 -- 通过浏览器访问容器中的应用:`http://192.168.137.128:38080/youmeek/`,可以看到 jar 应用的首页可以访问 - -## Docker 基本命令 - -- 官网文档: - -> 镜像仓库 - -- `docker pull`:从仓库下载镜像到本地 - - `docker pull centos:latest`:获取 CentOS 默认版本镜像 - - `docker pull centos:7.3.1611`:获取 CentOS 7 镜像,下载大小 70M 左右,下面的操作基于此镜像 - - `docker pull centos:6.8`:获取 CentOS 6 镜像 - - `docker pull registry.cn-hangzhou.aliyuncs.com/chainone/centos7-jdk8`:获取别人做好的阿里云镜像 - - 其他版本标识可以查看: -- `docker login`:登录到一个镜像仓库。默认登录的是官网的仓库: - - 登录阿里云仓库格式:`sudo docker login --username=阿里云邮箱 你在阿里云自己添加的仓库地址` - - 比如我是这个:`docker login --username=363379444@qq.com registry.cn-shenzhen.aliyuncs.com`,你完整的登录地址你需要访问:,在你自己创建的仓库中去查看那份详细操作指南上的地址 - - 密码就是你首次访问:,弹窗出来让你设置的那个密码,如果忘记了重新设置下即可,重设地址:,右上角有一个:修改docker登录密码。 -- `docker push` :将一个镜像 push 到 registry 仓库中 - - `docker push myapache:v1` -- `docker search`:从 registry 仓库搜索镜像 - - `docker search -s 3 centos`,参数 `-s 数字`:表示筛选出收藏数(stars值)大于等于 3 的镜像 - -> 本地镜像管理 - -- `docker images`:显示本地所有的镜像列表 - - 关注 REPOSITORY(名称),TAG(标签),IMAGE ID(镜像ID)三列 -- `docker images centos`:查看具体镜像情况 -- `docker rmi`:删除镜像,一般删除镜像前要先删除容器,不然如果镜像有被容器调用会报错 - - `docker rmi 容器ID`:删除具体某一个镜像 - - `docker rmi 仓库:Tag`:删除具体某一个镜像 - - `docker rmi $(docker images -q)`,删除所有镜像 -    - `docker rmi -f $(docker images -q)`,强制删除所有镜像 -- `docker tag`:为镜像打上标签 - - `docker tag -f ubuntu:14.04 ubuntu:latest`,-f 意思是强制覆盖 - - 同一个IMAGE ID可能会有多个TAG(可能还在不同的仓库),首先你要根据这些 image names 来删除标签,当删除最后一个tag的时候就会自动删除镜像; - - `docker rmi 仓库:Tag`,取消标签(如果是镜像的最后一个标签,则会删除这个镜像) -- `docker build`:使用 Dockerfile 创建镜像(推荐) - - `docker build --rm -t runoob/ubuntu:v1 .`,参数 `-t`,表示:-tag,打标签 -- `docker history`:显示生成一个镜像的历史命令 -- `docker save`:将一个镜像保存为一个 tar 包,带 layers 和 tag 信息(导出一个镜像) - - `docker save 镜像ID -o /opt/test.tar` -- `docker load`:从一个 tar 包创建一个镜像(导入一个镜像) - - `docker load -i /opt/test.tar` - - -> 容器管理操作 - -- `docker ps`:列出当前所有 **正在运行** 的容器 - - `docker ps -a`:列出所有的容器(包含历史,即运行过的容器) - - `docker ps -l`:列出最近一次启动的container - - `docker ps -q`:列出最近一次运行的container ID - - `docker ps -n x`:显示最后 x 个容器,不管是正在运行或是已经停止的 -- `docker inspect 容器ID`:查看容器的全面信息,用 JSON 格式输出 - - 获取容器中的 IP:`docker inspect -f '{{.NetworkSettings.IPAddress}}' 容器ID` - - 给容器重新设置 IP 和 子网掩码,需要在宿主上:`ifconfig 容器ID 192.168.200.1 netmask 255.255.255.0` -- `docker top 容器ID`:显示容器的进程信息 -- `docker events`:得到 docker 服务器的实时的事件 -- `docker logs -f 容器ID`:查看容器日志 - - `docker logs 容器ID`,获取守护式容器的日志 - - `docker logs -f 容器ID`,不断监控容器日志,类似 tail -f - - `docker logs -ft 容器ID`,在 -f 的基础上又增加 -t 表示为每条日志加上时间戳,方便调试 - - `docker logs --tail 10 容器ID`,获取日志最后 10 行 - - `docker logs --tail 0 -f 容器ID`,跟踪某个容器的最新日志而不必读取日志文件 -- `docker wait` :阻塞到一个容器,直到容器停止运行 -- `docker export` :将容器整个文件系统导出为一个tar包,不带layers、tag等信息 -- `docker port` :显示容器的端口映射 - -> 容器生命周期管理 - -- `docker run` - - `docker run --name myDockerNameIsGitNavi -i -t centos /bin/bash`,在 centos 容器下运行 shell bash。 - - `-i -t` 分别表示保证容器中的 STDIN 开启,并分配一个伪 tty 终端进行交互,这两个是合着用。 - - `--name` 是给容器起了一个名字(如果没有主动给名字,docker 会自动给你生成一个)容器的名称规则:大小写字母、数字、下划线、圆点、中横线,用正则表达式来表达就是:[a-zA-Z0-9_*-] - - `-d` 容器运行在后台。 - - `-p 8080:80` 表示端口映射,将宿主机的8080端口转发到容器内的80端口。 - - `docker run --rm --name myDockerNameIsGitNavi -i -t centos /bin/bash`,在 centos 容器下运行 shell bash。 - - `--rm`,表示退出即删除容器,一般用在做实验测试的时候 - - `docker run --restart=always -i -t centos /bin/bash`,--restart=always 表示停止后会自动重启 - - `docker run --restart=on-failure:5 -i -t centos /bin/bash`,--restart=on-failure:5 表示停止后会自动重启,最多重启 5 次 - - `docker run -i -t -v /opt/setups/:/opt/software/ 镜像ID /bin/bash`,启动容器,并进入 shell,同时挂载宿主机和容器的目录 - - `-v:表示需要将本地哪个目录挂载到容器中,格式:-v <宿主机目录>:<容器目录> ` - - `docker run -v /java_logs/:/opt/ -d -p 58080:8080 --name myDockerNameIsGitNavi myCustomImageName:0.1 /root/run.sh`,运行容器中 Spring Boot 应用 - - `-d`:表示以“守护模式”执行/root/run.sh脚本,此时 Tomcat 控制台不会出现在输出终端上。 - - `-p`:表示宿主机与容器的端口映射,此时将容器内部的 8080 端口映射为宿主机的 58080 端口,这样就向外界暴露了 58080 端口,可通过 Docker 网桥来访问容器内部的 8080 端口了。 - - `--name`:表示容器名称,用一个有意义的名称命名即可 - - `docker run -d -p 58080:8080 --name myDockerNameIsGitNavi myCustomImageName:0.1 /root/run.sh`,运行容器中 Spring Boot 应用 -- 进入容器后退出,输入:`exit` 回车 -- `docker start`,重新启动已经停止的容器 - - `docker start 容器ID` -- `docker attach`:连接上正在运行中的容器, 被 attach 上去的容器必须正在运行的才可以 - - `docker attach 容器ID`:重新进入容器终端中 -- `docker stop` -- `docker restart` -- `docker kill 容器ID/容器名称`, -- `docker rm`,删除容器,一般报类似错误就需要这样做:`docker: Error response from daemon: Conflict. The container name XXXXX` - - `docker rm 容器ID`,删除指定容器(该容器必须是停止的) - - `docker rm -f 容器ID`,删除指定容器(该容器可以是正在运行的) - - `docker rm $(docker ps -a -q)`,删除所有容器 -- `docker pause/unpause` -- `docker create` -- `docker exec`:对守护式的容器里面执行命令,方便对正在运行的容器进行维护、监控、管理 - - `docker exec -i -t 容器ID/容器名称 /bin/bash`,进入正在运行的 docker 容器,并启动终端交互 - - `docker exec -d 容器ID/容器名称 touch /opt/test.txt`,已守护式的方式进入 docker 容器,并创建一个文件 -- `docker stop 容器ID/容器名称`:停止容器 -- `docker commit` - 把容器打成镜像sudo docker commit a6c28e3f1ec4 ryzebo/docker-nodejs-test:0.1 - a6c28e3f1ec4 是容器的id - ryzebo 是你注册的https://store.docker.com/的名字,如果你没有的话,那需要先注册 - docker-nodejs-test 是你为该镜像起的名字 - :0.1 是镜像的版本号,默认是latest版本 - - 在提交镜像时指定更多的数据(包括标签)来详细描述所做的修改 - sudo docker commit -m="A new custom image" --author="James Turnbull" 4aab3ce3cb76 jamtur01/apache2:webserver -- `docker cp`:从容器里向外拷贝文件或目录 - - `docker cp Name:/container_path to_path` - - `docker cp ID:/container_path to_path` -- `docker diff`:显示容器文件系统的前后变化 - - - -版本信息 - -- `docker version`,查看docker版本 -- `docker info`,显示docker系统的信息 - -====================================================== - -删除老的(一周前创建)容器 - -docker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm - -docker version 查看版本号 -docker pull hello-world #下载镜像 -docker images #查看镜像 -docker ps -a #查看当前启动的容器进程 -docker ps -a -l #列出最后一次运行的容器 - -docker rm 容器ID #移除容器 - -docker ps //查看系统中运行的docker容器 -docker kill [container] //删除docker容器 -docker stop [container] //停止正在运行的docker容器 -docker run //运行镜像,生成容器 -docker images //查看系统中存在的docker镜像 -docker rmi [image] //删除镜像 -docker build //生成镜像 -docker pull //拉取镜像 -docker push //上传镜像 -docker search //搜索镜像 - - - -运行一个镜像 -docker run -i -t -p 3000:3000 ubuntu:16.04 /bin/bash --i 显示info级别log信息 --t 显示控制台 --p 3000:3000 把容器(下面有解释)的3000端口映射到本机3000端口 - -那就是把修改后的系统再打为iso就可以了。即,把容器再打为镜像即可。 -退出容器 -查看容器 docker ps -a - - -查看镜像:docker images - - -上传镜像 - -那么镜像想要被别人使用,就要上传到镜像管理平台,即https://store.docker.com/,就像代码要放到github一样 - -下面是上传步骤: - - 登录docker login - - 上传docker push ryzebo/docker-nodejs-test:0.1 - - - 此时在https://store.docker.com/搜索ryzebo/docker-nodejs-test(搜索你自己的哦),就会看到你刚刚上传的镜像了 - - - -创建一个要进行修改的定制容器 -sudo docker run -i -t ubuntu /bin/bash -安装apache软件包 -apt-get -yqq update -apt-get -y install apache2 -退出当前容器 -检查新创建的镜像 -sudo docker images jamtur01/apache2 - -使用docker inspect查看新创建的镜像详细信息 -sudo docker inspect jamtur01/apache2:webserver -从提交的镜像运行一个新容器 -sudo docker run -t -i jamtur01/apache2:webserver /bin/bash - - - -用以下命令,根据某个“容器 ID”来创建一个新的“镜像”: -docker commit 57c312bbaad1 huangyong/javaweb:0.1 -docker commit 89a47b5b749e lin_javaweb:0.1 -docker run -d -p 58080:8080 --name javaweb huangyong/javaweb:0.1 /root/run.sh -稍作解释: - -d:表示以“守护模式”执行/root/run.sh脚本,此时 Tomcat 控制台不会出现在输出终端上。 - -p:表示宿主机与容器的端口映射,此时将容器内部的 8080 端口映射为宿主机的 58080 端口,这样就向外界暴露了 58080 端口,可通过 Docker 网桥来访问容器内部的 8080 端口了。 - --name:表示容器名称,用一个有意义的名称命名即可。 -在浏览器中,输入以下地址,即可访问 Tomcat 首页: -http://192.168.65.132:58080/ - -## Dockerfile 解释 - - - - - -## Dockerfile 部署 - -- 目标:Spring Boot 应用 -- CentOS 7.3 -- jar 名称:skb-user-0.0.1-SNAPSHOT.jar -- 打算用的宿主机端口:9096 -- Dockerfile 文件和 jar 文件存放在宿主机目录:/opt/zch -- Dockerfile 内容如下: - -``` bash -FROM java:8-jre -MAINTAINER skb-user zch - -ADD skb-user-0.0.1-SNAPSHOT.jar /usr/local/skb/user/ - -CMD ["java", "-Xmx500m", "-jar", "/usr/local/skb/user/skb-user-0.0.1-SNAPSHOT.jar", "--spring.profiles.active=test"] - -EXPOSE 9096 -``` - -- 开始构建: - - `cd /opt/zch` - - `docker build . --tag="skb/user:v1.0.1"` - - `docker run -d -p 9096:9096 -v /usr/local/logs/:/opt/ --name="skbUser1.0.0" --net=host skb/user:v1.0.1` - - 查看启动后容器列表:`docker ps` - - jar 应用的日志是输出在容器的 /opt 目录下,因为我们上面用了挂载,所在在我们宿主机的 /usr/local/logs 目录下可以看到输出的日志 -- 防火墙开放端口: - - `firewall-cmd --zone=public --add-port=9096/tcp --permanent` - - `firewall-cmd --reload` - - - - - - - - - - -该文件名就叫Dockerfile,注意大小写,没有后缀,否则会报错。 - - -Dockerfile : 脚本化创建镜像 -Docker-compose:脚本化批量创建容器 - - -用dockerfile构建镜像 -并不推荐使用docker commit的方法来构建镜像,相反推荐使用Dockerfile的定义文件和docker build命令来构建镜像。Dockerfile使用基于DLS语法的指令来构建一个Docker镜像,之后使用docker build命令基于该dockerfile中的指令构建一个新的镜像。步骤:(我们将创建一个包含简单web服务器的docker镜像) - - 创建一个目录并在里面创建初始化的Dockerfile - - mkdir static_web - cd static_web - touch Dockerfile - - dockerfile文件内容 - - #第一个Dockerfile - #Version:0.0.1 - FROM ubuntu:14.04 - MAINTAINER James Turnbull "james@example.com" - RUN apt-get update - RUN apt-get install -y nginx - RUN echo 'Hi, I am in your container' > /usr/share/nginx/html/index.html - expose 80 - dockerfile指令解释 - Docker大体按照如下流程执行Dockerfile中的指令 - Docker从基础镜像运行一个容器。 - 执行一条指令,对容器做出修改。 - 执行类似docker commit的操作,提交一个新的镜像层。 - Docker在基于刚提交的镜像运行一个新容器。 - 执行Dockerfile中的下一条指令,直到所有指令都执行完毕。 - 基于dockerfile镜像构建新镜像 - 执行docker build命令时,dockerfile中的指令都会被执行并且被提交,并且在该命令成功结束后返回一个新镜像。 - - #运行Dockerfile - cd static_web - sudo docker build -t="jamtur01/static_web" . - - 使用docker build命令来构建新镜像,通过-t为新镜像设置了仓库和名称。在本例仓库为jamtur01,镜像名为static_web。建议为自己的镜像设置合适的名字以方便追踪和管理。也可以设置标签,如: - - sudo docker build -t="jamtur01/static_web:v1" . - - 上面告诉docker到本地目录中去找Dockerfile文件,也可以指定一个Git仓库的源地址来指定Dockerfile的位置。 - - sudo docker build -t="jamtur01/static_web:v1 git@github.com:jamtur01/docker-static_web - -忽略dockerfile的构建缓存 - -sudo docker build --no-cache -t="jamtur01/static_web" - -查看新镜像 - -sudo docker images jamtur01/static_web - -查看镜像如何构建出来的 - -sudo docker history22d47c8cb3jkk - -从新镜像启动一个容器 - -sudo docker run -d -p 80 --name static_web jamtur01/static_web nginx -g "daemon off;" - --d:说明在后台运行 --p:控制docker在运行时应该公开哪些网络端口给宿主机,-p还可以灵活的管理容器和宿主机之间的端口映射关系 - -sudo docker run -d -p 80:80 --name static_web jamtur01/static_web nginx -g "daemon off;" -sudo docker run -d -p 8080:80 --name static_web jamtur01/static_web nginx -g "daemon off;" -#端口限制在特定的IP上 -sudo docker run -d -p 127.0.0.1:8080:80 --name static_web jamtur01/static_web nginx -g "daemon off;" - --P:可以用来对外公开在Dockerfile中EXPOSE指令中设置的所有端口 - -sudo docker run -d -P --name static_web jamtur01/static_web nginx -g "daemon off;" - -运行一个容器时,Docker可以通过两种方法来在宿主机上分配端口。 - - Docker可以在宿主机上随机选择一个位于49153~65535的一个比较大的端口好来映射到容器中的80端口上。 - 可以在Docker宿主机中指定一个具体的端口好来映射到容器中的80端口上。 - -查看docker端口映射情况 - -sudo docker ps -l -##指定要查看映射情况的容器ID和容器的端口号 -sudo docker port container_id 80 - - - - - - -指定基础image:`FROM :` -指定镜像创建者信息:MAINTAINER - -RUN -ENTRYPOINT入口点 - - -CMD -ENV -ENV = = -WORKDIR 指定工作目录 -USER 指定当前用户 -指定容器需要映射到宿主机器的端口 -EXPOSE [...] -映射一个端口 -EXPOSE port1 -相应的运行容器使用的命令 -docker run -p port1 image -映射多个端口 -EXPOSE port1 port2 port3 -相应的运行容器使用的命令 -docker run -p port1 -p port2 -p port3 image -还可以指定需要映射到宿主机器上的某个端口号 -docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image - - -从src复制文件到container的dest路径 -COPY -ADD - 是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件url,如果是压缩包会被自动解压。 - 是container中的绝对路径s - - -指定挂载点 -//设置指令,使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用,也可以共享给其他容器使用。 -VOLUME [""] -eg: -VOLUME ["/tmp/data"] - - -切换目录 -WORKDIR /path/to/workdir -在 /p1/p2 下执行 vim a.txt -WORKDIR /p1 WORKDIR p2 RUN vim a.txt - -在子镜像中执行 -ONBUILD - - -创建 Dockerfile 到 push 的一个证过程: - -docker-compose 管理多个容器 - -然后build该Dockerfile为一个镜像 -docker build --rm --no-cache=true -t docker-node-test . - - -t 设定镜像名字 docker-node-test - --rm 如果已存在docker-node-test镜像,则删除docker-node-test镜像 - --no-cache=true build时,禁止缓存 - - -Dockerfile其它指令可以在官网查看https://docs.docker.com/engine/reference/builder/ - -FROM , 从一个基础镜像构建新的镜像 - -FROM ubuntu -MAINTAINER , 维护者信息 - -MAINTAINER William -ENV , 设置环境变量 - -ENV TEST 1 -RUN , 非交互式运行shell命令 - -RUN apt-get -y update - -RUN apt-get -y install nginx -ADD , 将外部文件拷贝到镜像里,src可以为url - -ADD http://nicescale.com/ /data/nicescale.tgz -WORKDIR /path/to/workdir, 设置工作目录 - -WORKDIR /var/www -USER , 设置用户ID - -USER nginx -VULUME <#dir>, 设置volume - -VOLUME [‘/data’] -EXPOSE , 暴露哪些端口 - -EXPOSE 80 443 -ENTRYPOINT [‘executable’, ‘param1’,’param2’]执行命令 - -ENTRYPOINT ["/usr/sbin/nginx"] -CMD [“param1”,”param2”] - -CMD ["start"] - -docker创建、启动container时执行的命令,如果设置了ENTRYPOINT,则CMD将作为参数 -Dockerfile最佳实践 - -尽量将一些常用不变的指令放到前面 - -CMD和ENTRYPOINT尽量使用json数组方式 -通过Dockerfile构建image - -docker build csphere/nginx:1.7 . -镜像仓库Registry - -镜像从Dockerfile build生成后,需要将镜像推送(push)到镜像仓库。企业内部都需要构建一个私有docker registry,这个registry可以看作二进制的scm,CI/CD也需要围绕registry进行。 -部署registry - -mkdir /registry - -docker run -p 80:5000 -e STORAGE_PATH=/registry -v /registry:/registry registry:2.0 -推送镜像保存到仓库 - -假设192.168.1.2是registry仓库的地址: - -docker tag csphere/nginx:1.7 192.168.1.2/csphere/nginx:1.7 - -docker push 192.168.1.2/csphere/nginx:1.7 - - - -## 编排工具 - -Kubernetes -安装kubernetes,访问不了gcr.io怎么办? -http://www.datastart.cn/tech/2017/04/07/k8s-mirror.html -http://www.datastart.cn/tech/2017/02/20/k8s-deploy.html - -Marathon - -## 资料 - -- -- -- -- -- -- -- -- -- -- <> -- <> -- <> -- <> - - -====================================================== - -1.弄懂镜像的含义 -2.弄懂容器的含义 - - 交互式容器:sudo docker run -it centos:6 /bin/bash - - -it 表示创建交互式容器 - - centos:6 以仓库:Tag的形式指定镜像名称 - - /bin/bash 是容器对应的进程 - - 守护式容器:sudo docker run -d 镜像名 - -sudo docker ps 查看已经运行过容器的基本信息 -sudo docker stop 容器ID,停止守护式容器 -sudo service docker restart,重启 docker 服务,当修改了 docker 相关的一些配置 -sudo docker rm 容器ID,删除容器 - - - -创建镜像:创建dockerfile,然后进行 build, - -常规下,容器重启之后,容器的IP地址是会自动变的,所以一般容器互联一般不用IP,而是在启动 docker 容器的时候附加一个参数:--link=容器名:我们要给这个要连接的容器创建的别名 - - - - - -视频教程: -http://www.jikexueyuan.com/path/docker/ - -ubuntu下的安装 -视频教程:http://www.jikexueyuan.com/course/832_2.html?ss=1 -官网文档:http://docs.docker.com/installation/ubuntulinux/ -网络文章:http://segmentfault.com/a/1190000002485231 - -1.检查内涵版本,linux内核建议是3.8以后的,Ubuntu 12.04.3及以上版本的默认内核是3.8.0 x86_64,所以ubuntu12之后的版本都不用担心 -运行命令:uname -a -2.检查Device Mapper是否存在(Ubuntu 12.04 以上都装好了) -运行命令:ls -l /sys/class/misc/device-mapper,有输出内容就表示存在 - -Docker有很多种安装的选择,我们推荐您在Ubuntu下面安装,因为docker是在Ubuntu下面开发的,安装包测试比较充分,可以保证软件包的可用性。Mac, windows和其他的一些linux发行版本无法原生运行Docker,可以使用虚拟软件创建一个ubuntu的虚拟机并在里面运行docker。 - -官网说明: 支持 Ubuntu 12.04 以上版本 -https://docs.docker.com/linux/step_one/ -$ sudo apt-get update -$ sudo apt-get install -y curl -$ curl -fsSL https://get.docker.com/ | sh -安装后,查看下docker版本,检查是否安装成功: -$ sudo docker version - -看docker运行状态:sudo service docker status - -sudo docker run hello-world -这个命令会下载一个测试用的镜像并启动一个容器运行它。 - - -去除掉sudo -在Ubuntu下,在执行Docker时,每次都要输入sudo,同时输入密码,很累人的,这里微调一下,把当前用户执行权限添加到相应的docker用户组里面。 -# 添加一个新的docker用户组 -sudo groupadd docker -# 添加当前用户到docker用户组里,注意这里的yongboy为ubuntu server登录用户名 -sudo gpasswd -a yongboy docker -# 重启Docker后台监护进程 -sudo service docker restart -# 重启之后,尝试一下,是否生效 -docker version -#若还未生效,则系统重启,则生效 -sudo reboot - - -================================= - -帮助命令:docker --help -http://www.jingyuyun.com/article/11068.html - -搜索镜像:docker search 镜像名 - -下载镜像 -docker pull ubuntu命令,先将Ubuntu镜像下载到本地,默认使用的镜像标签是latest。 - -下载国内镜像加速: -http://dashboard.daocloud.io/mirror -http://dashboard.daocloud.io/nodes/new -拉取centos镜像:dao pull centos:6.8 - -https://help.aliyun.com/knowledge_detail/5974865.html -dockone.io/article/646 -http://blog.csdn.net/bwlab/article/details/50542261 -http://devdd.sinaapp.com/post-724.html -http://www.imike.me/2016/04/20/Docker%E4%B8%8B%E4%BD%BF%E7%94%A8%E9%95%9C%E5%83%8F%E5%8A%A0%E9%80%9F/ - - -容器命名 -docker run --name 容器名字 -i -t ubuntu /bin/bash - -运行镜像: -然后再运行docker run -i -t ubuntu /bin/bash, -在镜像中安装ping工具:docker run learn/tutorial apt-get install -y ping - -保存在镜像中的修改,变动: -http://www.docker.org.cn/book/docker/docer-save-changes-10.html - -退出镜像:exit -docker ps -a来查看当前系统中的容器列表: -删除容器:docker rm - -在镜像中安装SSH,方便管理: -http://www.jingyuyun.com/article/11134.html - - -docker 修改镜像地址 - -================================= -windows下的安装:(由于docker底层用了linux的技术,所以目前windows下的环境,其实本质也是有一个linux虚拟机,所以不建议在windows下使用) -http://www.jikexueyuan.com/course/832_3.html?ss=1 - - -技术资料 - -docker中文官网:http://www.docker.org.cn/ -中文入门课程:http://www.docker.org.cn/book/docker.html -docker学习笔记:http://www.open-open.com/lib/view/open1423703640748.html -深入浅出docker:http://www.infoq.com/cn/articles/docker-core-technology-preview -https://www.zybuluo.com/SailorXiao/note/327656 diff --git a/ELK-Install-And-Settings.md b/ELK-Install-And-Settings.md deleted file mode 100644 index d5e0c216..00000000 --- a/ELK-Install-And-Settings.md +++ /dev/null @@ -1,62 +0,0 @@ -# ELK(Elasticsearch、Logstash、Kibana)安装和配置 - -## 版本说明 - -- 本文包含了:Elasticsearch 2.4.X 和 Elasticsearch 5.2.X 和 Elasticsearch 5.5.X,请有针对性地选择。 - -## 教程说明 - - -- 官网: -- 官网总文档: -- 官网最终指南: -- 官网对各个系统的支持列表: -- 5.2 版本有一个设置的新特性必须了解,测试建议我们用 CentOS 7: -- Elasticsearch 开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful 风格接口,多数据源,自动搜索负载等。 -- Logstash 日志进行收集、分析,并将其存储供以后使用(如,搜索) -- kibana 为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助您汇总、分析和搜索重要数据日志。 - - -### Elasticsearch 部署 - -- 请看 Elasticsearch 专题文:[Elasticsearch 相关知识](Elasticsearch-Base.md) - - -### logstash - -- 请看 logstash 专题文:[logstash 相关知识](Logstash-Base.md) - -### 安装 Kibana - -- 选择一台机子安装即可,我选择:192.168.1.127 这台 -- 切换到存放目录:`cd /usr/program/elk` -- 解压:`tar zxvf kibana-4.6.1-linux-x86_64.tar.gz` -- 修改配置文件:`vim /usr/program/elk/kibana-4.6.1-linux-x86_64/config/kibana.yml`,打开下面注释并配置: - -``` nginx -server.port: 5601 #端口 -server.host: "192.168.1.127" #访问ip地址 -elasticsearch.url: "http://192.168.1.127:9200" #连接elastic -kibana.index: ".kibana" #在elastic中添加.kibana索引 -``` - -- 记得先切换到 elasticsearch 用户下,然后先启动 elasticsearch。先确保 elasticsearch 集群是启动的。 -- 再切换到 root 用户下,启动 kibana -- 带控制台的启动(比较慢):`/usr/program/elk/kibana-4.6.1-linux-x86_64/bin/kibana` -- 守护进程方式启动:`/usr/program/elk/kibana-4.6.1-linux-x86_64/bin/kibana -d` -- 守护进程方式停止:`ps -ef|grep kibana`,只能通过 kill pid 来结束 -- 然后你可以访问:`http://192.168.1.127:5601`,可以看到 kibana 的相关界面。 -- 在 logstash 安装这一步,如果你刚刚有按着我说的去做一个 elasticsearch 索引,那你此时不会看到这样的提示:`Unable to fetch mapping. Do you have indices matching the pattern?` - - 此时你可以直接点击 `create` 统计 `logstash-*` 格式的索引结果,看到相关内容 - - 如果你知道你的索引名称的规则,比如我现在要统计 Tomcat 的相关索引,我的索引名称是:`tomcat-log-*`,则我输入这个,点击:create 即可。 -- kibana 的高级用法请看我单独的一篇文章:[kibana 相关知识](Kibana-Base.md) - - -## 资料 - -- -- -- -- -- <> -- <> diff --git a/Gitlab-Install-And-Settings.md b/Gitlab-Install-And-Settings.md deleted file mode 100644 index cba852a4..00000000 --- a/Gitlab-Install-And-Settings.md +++ /dev/null @@ -1,152 +0,0 @@ -# Gitlab 安装和配置 - -## 本文前提 - -- 本文只讲解 Gitlab 的搭建配置相关,至于开发流程本质跟 Github 没啥区别的,所以读这篇文章建议最好是已经会了 Github 那种开发流程。 - -## 测试机子硬件最低建议 - -- CPU:1 core -- 内存:2G - -## 安装 - -- 我习惯使用 root 用户 -- 有开源版本和收费版本,各版本比较: -- 官网: -- 中文网: -- 官网下载: -- 安装的系统环境要求: - - 从文章看目前要求 ruby 2.3,用 yum 版本过低,那就源码安装 ruby 吧,官网当前最新是:2.4.1(大小:14M) -- 安装 ruby - - 下载: - - 解压:`tar zxvf ruby-2.4.1.tar.gz` - - 编译安装: - - `cd ruby-2.4.1` - - `./configure` - - `make`,过程有点慢 - - `make install` - - 默认安装到这个目录:`/usr/local` - - 查看当前版本号:`ruby -v` -- CentOS 6 安装流程: - - 当前(201703)的版本是:`GitLab Community Edition 9.0.0` - - `sudo yum install -y curl openssh-server openssh-clients postfix cronie` - - `sudo service postfix start` - - `sudo chkconfig postfix on` - - `sudo lokkit -s http -s ssh` - - `curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash` - - `sudo yum install gitlab-ce`,软件大小:272M,下载速度不稳定 - - `sudo gitlab-ctl reconfigure`,这个过程比较慢 -- 如果上面的下载比较慢,也有国内的镜像: - - 清华: - - -## 配置 - -- 配置域名 / IP - - 编辑配置文件:`sudo vim /etc/gitlab/gitlab.rb` - - 找到 13 行左右:`external_url 'http://gitlab.example.com'`,改为你的域名 / IP - - 重启服务:`sudo gitlab-ctl reconfigure` -- 前面的初始化配置完成之后,访问当前机子 IP:`http://192.168.1.111:80` -- 默认用户是 root,并且没有密码,所以第一次访问是让你设置你的 root 密码,我设置为:gitlab123456(至少 8 位数) -- 设置会初始化密码之后,你就需要登录了。输入设置的密码。 -- root 管理员登录之后常用的设置地址(请求地址都是 RESTful 风格很好懂,也应该不会再变了。): - - 用户管理: - - 用户组管理: - - 项目管理: - - 添加 SSH Keys: - - 给新创建的用户设置密码: - - 新创建的用户,他首次登录会要求他强制修改密码的,这个设定很棒! -- 普通用户登录之后常去的链接: - - 配置 SSH Keys: - - -## 权限 - -- 官网帮助文档的权限说明: - -### 用户组的权限 - -- 用户组有这几种权限的概念:`Guest、Reporter、Developer、Master、Owner` -- 这个概念在设置用户组的时候会遇到,叫做:`Add user(s) to the group`,比如链接: - -|行为|Guest|Reporter|Developer|Master|Owner| -|---|---|--:|---|---|---| -|浏览组|✓|✓|✓|✓|✓| -|编辑组| | | | |✓| -|创建项目| | | |✓|✓| -|管理组成员| | | | |✓| -|移除组| | | | |✓| - -### 项目组的权限 - -- 项目组也有这几种权限的概念:`Guest、Reporter、Developer、Master、Owner` - - `Guest`:访客 - - `Reporter`:报告者; 可以理解为测试员、产品经理等,一般负责提交issue等 - - `Developer`:开发者; 负责开发 - - `Master`:主人; 一般是组长,负责对Master分支进行维护 - - `Owner`:拥有者; 一般是项目经理 -- 这个概念在项目设置的时候会遇到,叫做:`Members`,比如我有一个组下的项目链接: - -|行为|Guest|Reporter|Developer|Master|Owner| -|---|---|--:|---|---|---| -|创建issue|✓|✓|✓|✓|✓| -|留言评论|✓|✓|✓|✓|✓| -|更新代码| |✓|✓|✓|✓| -|下载工程| |✓|✓|✓|✓| -|创建代码片段| |✓|✓|✓|✓| -|创建合并请求| | |✓|✓|✓| -|创建新分支| | |✓|✓|✓| -|提交代码到非保护分支| | |✓|✓|✓| -|强制提交到非保护分支| | |✓|✓|✓| -|移除非保护分支| | |✓|✓|✓| -|添加tag| | |✓|✓|✓| -|创建wiki| | |✓|✓|✓| -|管理issue处理者| | |✓|✓|✓| -|管理labels| | |✓|✓|✓| -|创建里程碑| | | |✓|✓| -|添加项目成员| | | |✓|✓| -|提交保护分支| | | |✓|✓| -|使能分支保护| | | |✓|✓| -|修改/移除tag| | | |✓|✓| -|编辑工程| | | |✓|✓| -|添加deploy keys| | | |✓|✓| -|配置hooks| | | |✓|✓| -|切换visibility level| | | | |✓| -|切换工程namespace| | | | |✓| -|移除工程| | | | |✓| -|强制提交保护分支| | | | |✓| -|移除保护分支| | | | |✓| - -### 批量从一个项目中的成员转移到另外一个项目 - -- 项目的设置地址: - - 有一个 Import 按钮,跳转到: - -### 限定哪些分支可以提交、可以 merge - -- 也是在项目设置里面: -- 设置 CI (持续集成) 的 key 也是在这个地址上设置。 - -## 使用 Gitlab 的一个开发流程 - Git flow - -- Git flow:我是翻译成:Git 开发流程建议(不是规范,适合大点的团队),也有一个插件叫做这个,本质是用插件来帮你引导做规范的流程管理。 -- 这几篇文章很好,不多说了: - - 比较起源的一个说明(英文): - - Git-flow 插件也是他开发的,插件地址: - - Git-flow 插件的一些相关资料: - - - - - - - - - - - - - - - -## 资料 - -- -- -- -- \ No newline at end of file diff --git a/Jenkins-Install-And-Settings.md b/Jenkins-Install-And-Settings.md deleted file mode 100644 index aed4b193..00000000 --- a/Jenkins-Install-And-Settings.md +++ /dev/null @@ -1,45 +0,0 @@ -# Jenkins 安装和配置 - - -## Jenkins 安装 - -- Jenkins 安装 - - 官网: - - 官网帮助中心: - - 官网使用 Tomcat 部署方式指导: - - 此时(20160207) Jenkins 最新版本为:**1.647** - - JDK 最低要求是 JDK 7,官网推荐是 JDK 8 - - 我个人习惯 `/opt` 目录下创建一个目录 `setups` 用来存放各种软件安装包;在 `/usr` 目录下创建一个 `program` 用来存放各种解压后的软件包,下面的讲解也都是基于此习惯 - - 我个人已经使用了第三方源:`EPEL、RepoForge`,如果你出现 `yum install XXXXX` 安装不成功的话,很有可能就是你没有相关源,请查看我对源设置的文章 - - Jenkins 下载:`wget http://mirrors.jenkins-ci.org/war/latest/jenkins.war` (大小:61 M) - - 我们假设这个 Tomcat 就是为了 Jenkins 专用的 - - 把下载下来的 jenkins.war 移到 Tomcat 的 webapps 目录下,比如我的是:`/usr/program/tomcat8/webapps` - - 把 Jenkins.war 改名为 ROOT.war:`mv jenkins.war ROOT.war` - - 删除 Tomcat 下 webapps 目录下多余的一些目录 - - 首次启动 Tomcat,让 Tomcat 解压 war - - 设置 JENKINS_HOME: - - 寻找 jenkins home 目录地址:`find / -name .jenkins`,我这边得到的结果是:`/root/.jenkins` - - 对在 Tomcat 文章中讲解的系统变量 `CATALINA_OPTS` 进行设置: - - 旧值: - ``` - CATALINA_OPTS="-server -Xms528m -Xmx528m -XX:PermSize=256m -XX:MaxPermSize=358m" - export CATALINA_OPTS - ``` - - 改为: - ``` - CATALINA_OPTS="-server -DJENKINS_HOME=/root/.jenkins -Xms528m -Xmx528m -XX:PermSize=256m -XX:MaxPermSize=358m" - export CATALINA_OPTS - ``` - - -- Jenkins 各个组件配置: - - 访问: - - -- 其他问题 - - 如果访问的时候报这个异常:`java.net.UnknownHostException`,可以查看这篇文章: - - -## 资料 - -- \ No newline at end of file diff --git a/Jira-Install-And-Settings.md b/Jira-Install-And-Settings.md deleted file mode 100644 index d29df51c..00000000 --- a/Jira-Install-And-Settings.md +++ /dev/null @@ -1,42 +0,0 @@ -# Jira 安装和配置 - - -## Jira 安装 - -- Jira 安装 - - 官网: - - 官网下载: - - 中文在线试用: - - 官网帮助说明: - - 官网中文语言包: - - Jira 6.3.6 网盘下载: - - Jira 6.3.6 中文语言包网盘下载: - - 环境要求: - - JDK 7 或更新版本; - - Mysql - - 我们要使用的版本:**atlassian-jira-6.3.6.tar.gz** - - 我个人习惯 `/opt` 目录下创建一个目录 `setups` 用来存放各种软件安装包;在 `/usr` 目录下创建一个 `program` 用来存放各种解压后的软件包,下面的讲解也都是基于此习惯 - - 我个人已经使用了第三方源:`EPEL、RepoForge`,如果你出现 `yum install XXXXX` 安装不成功的话,很有可能就是你没有相关源,请查看我对源设置的文章 - - 解压:`tar zxvf atlassian-jira-6.3.6.tar.gz` - - 修改目录名:`mv atlassian-jira-6.3.6/ jira6.3.6/` - - 移到我个人的安装目录下:`mv jira6.3.6/ /usr/program/` - - 创建存放数据目录:`mkdir -p /usr/program/jira6.3.6/data/` - - 设置环境变量: - - 编辑:`vim /etc/profile` - - 在文件尾部添加: - ``` ini - JIRA_HOME=/usr/program/jira6.3.6/data/ - export JIRA_HOME - ``` - - 刷新配置:`source /etc/profile` - - 运行:`/usr/program/jira6.3.6/bin/start-jira.sh` - - 访问:`http://192.168.0.111:8080/` - - 汉化:`cp JIRA-6.3.6-language-pack-zh_CN.jar /usr/program/jira6.3.6/atlassian-jira/WEB-INF/lib/` - - 配置过程: - - ![Jira 安装和配置](images/Jira-Install-And-Settings-a-1.jpg) - - ![Jira 安装和配置](images/Jira-Install-And-Settings-a-2.jpg) - - ![Jira 安装和配置](images/Jira-Install-And-Settings-a-3.jpg) - - ![Jira 安装和配置](images/Jira-Install-And-Settings-a-4.jpg) - - ![Jira 安装和配置](images/Jira-Install-And-Settings-a-5.jpg) - - ![Jira 安装和配置](images/Jira-Install-And-Settings-a-6.jpg) - - 重新激活页面地址:`http://192.168.0.111:8090/secure/admin/ViewLicense.jspa` \ No newline at end of file diff --git a/Kibana-Base.md b/Kibana-Base.md deleted file mode 100644 index 22febb5a..00000000 --- a/Kibana-Base.md +++ /dev/null @@ -1,16 +0,0 @@ -# kibana 知识 - -## 基础知识 - -- 官网文档: - - -## 案例 - - - - -## 资料 - -- <> -- <> \ No newline at end of file diff --git a/Maven-Install-And-Settings.md b/Maven-Install-And-Settings.md deleted file mode 100644 index 6a432db7..00000000 --- a/Maven-Install-And-Settings.md +++ /dev/null @@ -1,155 +0,0 @@ -# Maven 安装和配置 - - - -## Maven 安装 - -- Maven 安装 - - 官网: - - 官网下载: - - 历史版本下载: - - 此时(20160208) Maven 最新版本为:**3.3.9** - - Maven 3.3 的 JDK 最低要求是 JDK 7 - - 我个人习惯 `/opt` 目录下创建一个目录 `setups` 用来存放各种软件安装包;在 `/usr` 目录下创建一个 `program` 用来存放各种解压后的软件包,下面的讲解也都是基于此习惯 - - 我个人已经使用了第三方源:`EPEL、RepoForge`,如果你出现 `yum install XXXXX` 安装不成功的话,很有可能就是你没有相关源,请查看我对源设置的文章 - - 下载压缩包:`wget http://mirrors.cnnic.cn/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz` - - 解压:`tar zxvf apache-maven-3.3.9-bin.tar.gz` - - 修改目录名,默认的太长了:`mv apache-maven-3.3.9/ maven3.3.9/` - - 移到我个人习惯的安装目录下:`mv maven3.3.9/ /usr/program` - - 环境变量设置:`vim /etc/profile` - - 在文件最尾巴添加下面内容: - - ``` ini - # Maven - MAVEN_HOME=/usr/program/maven3.3.9 - PATH=$PATH:$MAVEN_HOME/bin - MAVEN_OPTS="-Xms256m -Xmx356m" - export MAVEN_HOME - export PATH - export MAVEN_OPTS - ``` - - - 刷新配置文件:`source /etc/profile` - - 测试是否安装成功:`mvn -version` - - -## Maven 配置 - -- 配置项目连接上私服 -- 全局方式配置: - -``` xml - - - - - - D:/maven/my_local_repository - - - - - - - - - - - nexus-releases - admin - admin123 - - - nexus-snapshots - admin - admin123 - - - - - - - nexus-releases - * - http://localhost:8081/nexus/content/groups/public - - - nexus-snapshots - * - http://localhost:8081/nexus/content/groups/public-snapshots - - - - - - - nexus - - - nexus-releases - http://nexus-releases - - true - - - true - - - - nexus-snapshots - http://nexus-snapshots - - true - - - true - - - - - - nexus-releases - http://nexus-releases - - true - - - true - - - - nexus-snapshots - http://nexus-snapshots - - true - - - true - - - - - - - - nexus - - - -``` - -- 项目级别: - - - - -## 资料 - -- -- -- -- -- -- -- -- \ No newline at end of file diff --git a/Mycat-Install-And-Settings.md b/Mycat-Install-And-Settings.md deleted file mode 100644 index 1341ee02..00000000 --- a/Mycat-Install-And-Settings.md +++ /dev/null @@ -1,73 +0,0 @@ -# Mycat 安装和配置 - -## 前提 - -- 局域网中有一台 IP:192.168.1.111 已经安装好了一个 MySQL 5.6 - -## 部署的环境 - -- 系统:CentOS 6.7 -- 系统 IP:192.168.1.112 -- JDK:jdk-8u72-linux-x64.tar.gz -- Mycat:Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz - -## Mycat 安装 - -- 官网(页头有一个 PDF 要记得下载,这本资料写得很好): -- 官网下载(官网下载地址很乱,如果哪天右边这个地址不行了,到官网加群问下吧): -- 项目 Github: -- 此时(20170122) 最新稳定版本为:**1.6**,下载下来的文件名称:**Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz** -- 安装前的准备: - - 这台机子必须装有 JDK,并且配置好 JAVA_HOME。JDK 的安装看: -- 开始安装: - - 给 Mycat 创建专属系统用户,并设置密码: - - `useradd mycat` - - `passwd mycat`,进入设置密码,我习惯测试的时候密码为:123456 - - 假设 Mycat 安装包的完整路径是:**/opt/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz** - - 解压:`cd /opt ; tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz` - - 移动解压的目录到官方建议的目录下:`mv /opt/mycat /usr/local/` - - 设置 Mycat 的环境变量 - - `vim /etc/profile`,添加如下内容: -``` nginx -export MYCAT_HOME=/usr/local/mycat -export PATH=$PATH:$MYCAT_HOME/bin -``` - - 刷新配置:`source /etc/profile` - - 到这里就安装好了,但是先不启动,需要先去配置相应的配置文件。 - -## Mycat 配置 - -- 使用 Mycat 这几个配置文件必定会改动到。这一个文件所代表的含义几句话说不了,还请你自己看下官网的文档。 - - `rule.xml`,设置分片规则。 - - `server.xml`,主要用于配置系统变量、用户管理、用户权限等。 - - `schema.xml`,用于设置 Mycat 的逻辑库、表、数据节点、dataHost 等内容,分库分表、读写分离等等都是在这里进行配置的 - - 其中特别注意的是分片节点的配置,如下,其中 db1,db2,db3 是需要我们自己在 IP 为:192.168.1.111 这台机子上人工创建这三个空白数据库。 -``` nginx - - - -``` -- 假设你上面的配置文件都配置好了: - - 开放 8066 端口 - - 如果只是临时测试,可以临时关掉防火墙:`service iptables stop` - - 不然就添加防火墙规则: - - 添加规则:`sudo iptables -I INPUT -p tcp -m tcp --dport 8066 -j ACCEPT` - - 保存规则:`sudo service iptables save` - - 重启 iptables:`sudo service iptables restart` -- 启动/停止/重启 - - 启动有两种,一种是后台启动,启动后看不到任何信息。一种是控制台启动,启动后进入 Mycat 的控制台界面,显示当前 Mycat 的活动信息,按 Ctrl + C 停止控制台的时候 Mycat 也跟着停止。 - - 进入 Mycat 目录:`cd /usr/local/mycat/bin` - - 后台启动:`./mycat start`,看到日志可以这样看:`tail -f /usr/local/mycat/logs/mycat.log` - - 控制台启动:`./mycat console` - - 重启:`./mycat restart` - - 停止:`./mycat stop` -- 连接 Mycat - - 连接 Mycat 的过程跟连接普通的 MySQL 表面上是没啥区别的,使用的命令都是一个样。但是需要注意的是,很容易出问题。对连接客户端有各种意外,目前我做了总结: - - 连接命令:`mysql -h192.168.1.112 -uroot -p -P8066`,然后输入 mycat 的 root 用户密码(在上面介绍的 server.xml 中配置的) - - **不建议** 的连接方式: - - SQLyog 软件,我这边是报:*find no Route:select * from `youmeek_nav`.`nav_url` limit 0, 1000* - - Windows 系统下使用 cmd 去连接,我这边是报:*ERROR 1105 (HY000): Unknown character set: 'gbk'* - - MySQL-Front 软件,没用过,但是别人说是有兼容性问题 - - **建议** 的连接方式: - - Navicat for mysql 软件 - - Linux 下的 MySQL 客户端命令行 diff --git a/Mysql-Install-And-Settings.md b/Mysql-Install-And-Settings.md deleted file mode 100644 index 32c8fa3c..00000000 --- a/Mysql-Install-And-Settings.md +++ /dev/null @@ -1,175 +0,0 @@ -# MySQL 安装和配置 - - -## MySQL 安装 - -- 假设当前用户为:root -- Mysql 安装 - - 官网: - - 官网下载: - - 官网 5.5 下载: - - 官网 5.6 下载: - - 官网 5.7 下载: - - 官网帮助中心: - - 此时(20160210) Mysql 5.5 最新版本为:**5.5.48** - - 此时(20170130) Mysql 5.6 最新版本为:**5.6.35** - - 此时(20160210) Mysql 5.7 最新版本为:**5.7.11** - - 我个人习惯 `/opt` 目录下创建一个目录 `setups` 用来存放各种软件安装包;在 `/usr` 目录下创建一个 `program` 用来存放各种解压后的软件包,下面的讲解也都是基于此习惯 - - 我个人已经使用了第三方源:`EPEL、RepoForge`,如果你出现 `yum install XXXXX` 安装不成功的话,很有可能就是你没有相关源,请查看我对源设置的文章 - - Mysql 5.6 下载:`wget http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.35.tar.gz` (大小:31 M) - - Mysql 5.7 下载:`wget http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.11.tar.gz` (大小:47 M) - - 我们这次安装以 5.6 为实例 - - 进入下载目录:`cd /opt/setups` - - 解压压缩包:`tar zxvf mysql-5.6.35.tar.gz` - - 移到解压包:`mv /opt/setups/mysql-5.6.35 /usr/program/` - - 安装依赖包、编译包:`yum install -y make gcc-c++ cmake bison-devel ncurses-devel` - - 进入解压目录:`cd /usr/program/mysql-5.6.35/` - - 生成安装目录:`mkdir -p /usr/program/mysql/data` - - 生成配置(使用 InnoDB):`cmake -DCMAKE_INSTALL_PREFIX=/usr/program/mysql -DMYSQL_DATADIR=/usr/program/mysql/data -DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS:STRING=utf8 -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DENABLED_LOCAL_INFILE=1` - - 更多参数说明可以查看: - - 编译:`make`,这个过程比较漫长,一般都在 30 分钟左右,具体还得看机子配置,如果最后结果有 error,建议删除整个 mysql 目录后重新解压一个出来继续处理 - - 安装:`make install` - - 配置开机启动: - - `cp /usr/program/mysql-5.6.35/support-files/mysql.server /etc/init.d/mysql` - - `chmod 755 /etc/init.d/mysql` - - `chkconfig mysql on` - - 复制一份配置文件: `cp /usr/program/mysql-5.6.35/support-files/my-default.cnf /etc/my.cnf` - - 删除安装的目录:`rm -rf /usr/program/mysql-5.6.35/` - - 添加组和用户及安装目录权限 - - `groupadd mysql` #添加组 - - `useradd -g mysql mysql -s /bin/false` #创建用户mysql并加入到mysql组,不允许mysql用户直接登录系统 - - `chown -R mysql:mysql /usr/program/mysql/data` #设置MySQL数据库目录权限 - - 初始化数据库:`/usr/program/mysql/scripts/mysql_install_db --basedir=/usr/program/mysql --datadir=/usr/program/mysql/data --skip-name-resolve --user=mysql` - - 开放防火墙端口: - - `iptables -I INPUT -p tcp -m tcp --dport 3306 -j ACCEPT` - - `service iptables save` - - `service iptables restart` - - 禁用 selinux - - 编辑配置文件:`vim /etc/selinux/config` - - 把 `SELINUX=enforcing` 改为 `SELINUX=disabled` - - 常用命令软连接,才可以在终端直接使用:mysql 和 mysqladmin 命令 - - `ln -s /usr/program/mysql/bin/mysql /usr/bin` - - `ln -s /usr/program/mysql/bin/mysqladmin /usr/bin` - - `ln -s /usr/program/mysql/bin/mysqldump /usr/bin` - - `ln -s /usr/program/mysql/bin/mysqlslap /usr/bin` - - -## MySQL 配置 - -- 官网配置参数解释: -- 找一下当前系统中有多少个 my.cnf 文件:`find / -name "my.cnf"`,我查到的结果: - -``` nginx -/etc/my.cnf -/usr/program/mysql/my.cnf -/usr/program/mysql/mysql-test/suite/ndb/my.cnf -/usr/program/mysql/mysql-test/suite/ndb_big/my.cnf -............. -/usr/program/mysql/mysql-test/suite/ndb_rpl/my.cnf -``` - - -- 保留 **/etc/my.cnf** 和 **/usr/program/mysql/mysql-test/** 目录下配置文件,其他删除掉。 -- 我整理的一个单机版配置说明(MySQL 5.6,适用于 1G 内存的服务器): - - [my.cnf](MySQL-Settings/MySQL-5.6/1G-Memory-Machine/my-for-comprehensive.cnf) - -## 修改 root 账号密码 - -- 启动 Mysql 服务器:`service mysql start` -- 查看是否已经启动了:`ps aux | grep mysql` -- 默认安装情况下,root 的密码是空,所以为了方便我们可以设置一个密码,假设我设置为:123456 -- 终端下执行:`mysql -uroot` - - 现在进入了 mysql 命令行管理界面,输入:`SET PASSWORD = PASSWORD('123456');FLUSH PRIVILEGES;` -- 修改密码后,终端下执行:`mysql -uroot -p` - - 根据提示,输入密码进度 mysql 命令行状态。 -- 如果你在其他机子上连接该数据库机子报:**Access denied for user 'root'@'localhost' (using password: YES)** - - 解决办法: - - 在终端中执行:`service mysql stop` - - 在终端中执行(前面添加的 Linux 用户 mysql 必须有存在):`/usr/program/mysql/bin/mysqld --skip-grant-tables --user=mysql` - - 此时 MySQL 服务会一直处于监听状态,你需要另起一个终端窗口来执行接下来的操作 - - 在终端中执行:`mysql -u root mysql` - - 把密码改为:123456,进入 MySQL 命令后执行:`UPDATE user SET Password=PASSWORD('123456') where USER='root';FLUSH PRIVILEGES;` - - 然后重启 MySQL 服务:`service mysql restart` - -## 连接报错:"Host '192.168.1.133' is not allowed to connect to this MySQL server" - -- 不允许除了 localhost 之外去连接,解决办法,进入 MySQL 命令行,输入下面内容: -- `GRANT ALL PRIVILEGES ON *.* TO '数据库用户名'@'%' IDENTIFIED BY '数据库用户名的密码' WITH GRANT OPTION;` - -## MySQL 主从复制 - -### 环境说明和注意点 - -- 假设有两台服务器,一台做主,一台做从 - - MySQL 主信息: - - IP:**12.168.1.113** - - 端口:**3306** - - MySQL 从信息: - - IP:**12.168.1.115** - - 端口:**3306** -- 注意点 - - 主 DB server 和从 DB server 数据库的版本一致 - - 主 DB server 和从 DB server 数据库数据一致 - - 主 DB server 开启二进制日志,主 DB server 和从 DB server 的 server-id 都必须唯一 -- 优先操作: - - **把主库的数据库复制到从库并导入** - -### 主库机子操作 - -- 主库操作步骤 - - 创建一个目录:`mkdir -p /usr/program/mysql/data/mysql-bin` - - 主 DB 开启二进制日志功能:`vim /etc/my.cnf`, - - 添加一行:`log-bin = /usr/program/mysql/data/mysql-bin` - - 指定同步的数据库,如果不指定则同步全部数据库,其中 ssm 是我的数据库名:`binlog-do-db=ssm` - - 主库关掉慢查询记录,用 SQL 语句查看当前是否开启:`SHOW VARIABLES LIKE '%slow_query_log%';`,如果显示 OFF 则表示关闭,ON 表示开启 - - 重启主库 MySQL 服务 - - 进入 MySQL 命令行状态,执行 SQL 语句查询状态:`SHOW MASTER STATUS;` - - 在显示的结果中,我们需要记录下 **File** 和 **Position** 值,等下从库配置有用。 - - 设置授权用户 slave01 使用 123456 密码登录主库,这里 @ 后的 IP 为从库机子的 IP 地址,如果从库的机子有多个,我们需要多个这个 SQL 语句。 - - ``` SQL - grant replication slave on *.* to 'slave01'@'192.168.1.135' identified by '123456'; - flush privileges; - ``` - - -### 从库机子操作 - - -- 从库操作步骤 - - 从库开启慢查询记录,用 SQL 语句查看当前是否开启:`SHOW VARIABLES LIKE '%slow_query_log%';`,如果显示 OFF 则表示关闭,ON 表示开启。 - - 测试从库机子是否能连上主库机子:`mysql -h 192.168.1.105 -u slave01 -p`,必须要连上下面的操作才有意义。 - - 由于不能排除是不是系统防火墙的问题,所以建议连不上临时关掉防火墙:`service iptables stop` - - 或是添加防火墙规则: - - 添加规则:`iptables -I INPUT -p tcp -m tcp --dport 3306 -j ACCEPT` - - 保存规则:`service iptables save` - - 重启 iptables:`service iptables restart` - - 修改配置文件:`vim /etc/my.cnf`,把 server-id 改为跟主库不一样 - - 在进入 MySQL 的命令行状态下,输入下面 SQL: - - ``` SQL - CHANGE MASTER TO - master_host='192.168.1.113', - master_user='slave01', - master_password='123456', - master_port=3306, - master_log_file='mysql3306-bin.000006',>>>这个值复制刚刚让你记录的值 - master_log_pos=1120;>>>这个值复制刚刚让你记录的值 - ``` - -- 执行该 SQL 语句,启动 slave 同步:`START SLAVE;` -- 执行该 SQL 语句,查看从库机子同步状态:`SHOW SLAVE STATUS;` -- 在查看结果中必须下面两个值都是 Yes 才表示配置成功: - - `Slave_IO_Running:Yes` - - 如果不是 Yes 也不是 No,而是 Connecting,那就表示从机连不上主库,需要你进一步排查连接问题。 - - `Slave_SQL_Running:Yes` -- 如果你的 Slave_IO_Running 是 No,一般如果你是在虚拟机上测试的话,从库的虚拟机是从主库的虚拟机上复制过来的,那一般都会这样的,因为两台的 MySQL 的 UUID 值一样。你可以检查从库下的错误日志:`cat /usr/program/mysql/data/mysql-error.log` - - 如果里面提示 uuid 错误,你可以编辑从库的这个配置文件:`vim /usr/program/mysql/data/auto.cnf`,把配置文件中的:server-uuid 值随便改一下,保证和主库是不一样即可。 - - - - - -## 资料 - -- diff --git a/Mysql-Optimize.md b/Mysql-Optimize.md deleted file mode 100644 index 88f1209d..00000000 --- a/Mysql-Optimize.md +++ /dev/null @@ -1,158 +0,0 @@ -# MySQL 优化 - - -- 下面说的优化基于 MySQL 5.6,理论上 5.5 之后的都算适用,具体还是要看官网 - -## 服务状态查询 - -- 查看当前数据库的状态,常用的有: - - 查看系统状态:`SHOW STATUS;` - - 查看刚刚执行 SQL 是否有警告信息:`SHOW WARNINGS;` - - 查看刚刚执行 SQL 是否有错误信息:`SHOW ERRORS;` - - 查看已经连接的所有线程状况:`SHOW PROCESSLIST;` - - 查看当前连接数量:`SHOW STATUS LIKE 'max_used_connections';` - - 查看变量,在 my.cnf 中配置的变量会在这里显示:`SHOW VARIABLES;` - - 查看当前MySQL 中已经记录了多少条慢查询,前提是配置文件中开启慢查询记录了. - - `SHOW STATUS LIKE '%slow_queries%';` - - 查询当前MySQL中查询、更新、删除执行多少条了,可以通过这个来判断系统是侧重于读还是侧重于写,如果是写要考虑使用读写分离。 - - `SHOW STATUS LIKE '%Com_select%';` - - `SHOW STATUS LIKE '%Com_update%';` - - `SHOW STATUS LIKE '%Com_delete%';` - - 显示MySQL服务启动运行了多少时间,如果MySQL服务重启,该时间重新计算,单位秒 - - `SHOW STATUS LIKE 'uptime';` - - 显示查询缓存的状态情况 - - `SHOW STATUS LIKE 'qcache%';` - - PS.下面的解释,我目前不肯定是对,还要再找下资料: - - - - - - - - - - 1. Qcache_free_blocks,缓存中相邻内存块的个数。数目大说明可能有碎片。如果数目比较大,可以执行: `flush query cache;` 对缓存中的碎片进行整理,从而得到一个空闲块。 - - 2. Qcache_free_memory,缓存中的空闲内存大小。如果 Qcache_free_blocks 比较大,说明碎片严重。 如果 Qcache_free_memory 很小,说明缓存不够用了。 - - 3. Qcache_hits,每次查询在缓存中命中时就增大该值。 - - 4. Qcache_inserts,每次查询,如果没有从缓存中找到数据,这里会增大该值 - - 5. Qcache_lowmem_prunes,因内存不足删除缓存次数,缓存出现内存不足并且必须要进行清理, 以便为更多查询提供空间的次数。返个数字最好长时间来看;如果返个数字在不断增长,就表示可能碎片非常严重,或者缓存内存很少。 - - 6. Qcache_not_cached # 没有进行缓存的查询的数量,通常是这些查询未被缓存或其类型不允许被缓存 - - 7. Qcache_queries_in_cache # 在当前缓存的查询(和响应)的数量。 - - 8. Qcache_total_blocks #缓存中块的数量。 - - - - -## my.cnf 常配置项 - -- `key_buffer_size`,索引缓冲区大小。 -- `query_cache_size`,查询缓存。 -- `max_connections = 1000`,MySQL 的最大并发连接数 -- ``, -- ``, -- ``, -- ``, -- ``, -- ``, -- ``, -- ``, - - -## 查询优化 - -- 使用 EXPLAIN 进行 SQL 语句分析:`EXPLAIN SELECT * FROM sys_user;` -- 得到的结果有下面几列: - - **id**,该列表示当前结果序号,无特殊意义,不重要 - - **select_type**,表示 SELECT 语句的类型,有下面几种 - - SIMPLE,表示简单查询,其中不包括连接查询和子查询 - - PRIMARY,表示主查询,或者是最外面的查询语句。比如你使用一个子查询语句,比如这条 SQL:`EXPLAIN SELECT * FROM (SELECT sys_user_id FROM sys_user WHERE sys_user_id = 1) AS temp_table;` - - 这条 SQL 有两个结果,其中有一个结果的类型就是 PRIMARY - - UNION,使用 UNION 的 SQL 是这个类型 - - DERIVED,在 SQL 中 From 后面子查询 - - SUBQUERY,子查询 - - 还有其他一些 - - **table**,表名或者是子查询的一个结果集 - - **type**,表示表的链接类型,分别有(以下的连接类型的顺序是从最佳类型到最差类型)**(这个属性重要)**: - - 性能好: - - system,表仅有一行,这是 const 类型的特列,平时不会出现,这个也可以忽略不计。 - - const,数据表最多只有一个匹配行,因为只匹配一行数据,所以很快,常用于 PRIMARY KEY 或者 UNIQUE 索引的查询,可理解为 const 是最优化的。 - - eq_ref,mysql 手册是这样说的:"对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了 const 类型。它用在一个索引的所有部分被联接使用并且索引是 UNIQUE(唯一键) 也不是 PRIMARY KEY(主键)"。eq_ref 可以用于使用 = 比较带索引的列。 - - ref,查询条件索引既不是 UNIQUE(唯一键) 也不是 PRIMARY KEY(主键) 的情况。ref 可用于 = 或 < 或 > 操作符的带索引的列。 - - ref_or_null,该联接类型如同 ref,但是添加了 MySQL 可以专门搜索包含 NULL 值的行。在解决子查询中经常使用该联接类型的优化。 - - 性能较差: - - index_merge,该联接类型表示使用了索引合并优化方法。在这种情况下,key 列包含了使用的索引的清单,key_len 包含了使用的索引的最长的关键元素。 - - unique_subquery,该类型替换了下面形式的IN子查询的ref: `value IN (SELECT primary_key FROM single_table WHERE some_expr)`。unique_subquery 是一个索引查找函数,可以完全替换子查询,效率更高。 - - index_subquery,该联接类型类似于 unique_subquery。可以替换 IN 子查询, 但只适合下列形式的子查询中的非唯一索引: `value IN (SELECT key_column FROM single_table WHERE some_expr)` - - range,只检索给定范围的行, 使用一个索引来选择行。 - - index,该联接类型与 ALL 相同, 除了只有索引树被扫描。这通常比 ALL 快, 因为索引文件通常比数据文件小。 - - 性能最差: - - ALL,对于每个来自于先前的表的行组合, 进行完整的表扫描。(性能最差) - - **possible_keys**,指出 MySQL 能使用哪个索引在该表中找到行。如果该列为 NULL,说明没有使用索引,可以对该列创建索引来提供性能。**(这个属性重要)** - - **key**,显示 MySQL 实际决定使用的键 (索引)。如果没有选择索引, 键是 NULL。**(这个属性重要)** - - **key**_len,显示 MySQL 决定使用的键长度。如果键是 NULL, 则长度为 NULL。注意:key_len 是确定了 MySQL 将实际使用的索引长度。 - - **ref**,显示使用哪个列或常数与 key 一起从表中选择行。 - - **rows**,显示 MySQL 认为它执行查询时必须检查的行数。**(这个属性重要)** - - **Extra**,该列包含 MySQL 解决查询的详细信息: - - Distinct:MySQL 发现第 1 个匹配行后, 停止为当前的行组合搜索更多的行。 - - Not exists:MySQL 能够对查询进行 LEFT JOIN 优化, 发现 1 个匹配 LEFT JOIN 标准的行后, 不再为前面的的行组合在该表内检查更多的行。 - - range checked for each record (index map: #):MySQL 没有发现好的可以使用的索引, 但发现如果来自前面的表的列值已知, 可能部分索引可以使用。 - - Using filesort:MySQL 需要额外的一次传递, 以找出如何按排序顺序检索行。 - - Using index: 从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。 - - Using temporary: 为了解决查询,MySQL 需要创建一个临时表来容纳结果。 - - Using where:WHERE 子句用于限制哪一个行匹配下一个表或发送到客户。 - - Using sort_union(...), Using union(...), Using intersect(...): 这些函数说明如何为 index_merge 联接类型合并索引扫描。 - - Using index for group-by: 类似于访问表的 Using index 方式,Using index for group-by 表示 MySQL 发现了一个索引, 可以用来查 询 GROUP BY 或 DISTINCT 查询的所有列, 而不要额外搜索硬盘访问实际的表。 -- **了解对索引不生效的查询情况 (这个属性重要)** - - 使用 LIKE 关键字的查询,在使用 LIKE 关键字进行查询的查询语句中,如果匹配字符串的第一个字符为“%”,索引不起作用。只有“%”不在第一个位置,索引才会生效。 - - 使用联合索引的查询,MySQL 可以为多个字段创建索引,一个索引可以包括 16 个字段。对于联合索引,只有查询条件中使用了这些字段中第一个字段时,索引才会生效。 - - 使用 OR 关键字的查询,查询语句的查询条件中只有 OR 关键字,且 OR 前后的两个条件中的列都是索引列时,索引才会生效,否则,索引不生效。 -- 子查询优化 - - MySQL 从 4.1 版本开始支持子查询,使用子查询进行 SELECT 语句嵌套查询,可以一次完成很多逻辑上需要多个步骤才能完成的 SQL 操作。 - - 子查询虽然很灵活,但是执行效率并不高。 - - 执行子查询时,MYSQL 需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响。 - - 优化: - - 可以使用连接查询(JOIN)代替子查询,连接查询时不需要建立临时表,其速度比子查询快。 - - -## 数据库结构优化 - -- 将字段很多的表分解成多个表 - - 对于字段较多的表,如果有些字段的使用频率很低,可以将这些字段分离出来形成新表。 - - 因为当一个表的数据量很大时,会由于使用频率低的字段的存在而变慢。 -- 增加中间表 - - 对于需要经常联合查询的表,可以建立中间表以提高查询效率。 - - 通过建立中间表,将需要通过联合查询的数据插入到中间表中,然后将原来的联合查询改为对中间表的查询。 -- 增加冗余字段 - - 设计数据表时应尽量遵循范式理论的规约,尽可能的减少冗余字段,让数据库设计看起来精致、优雅。但是,合理的加入冗余字段可以提高查询速度。 - - - -## 插入数据的优化(适用于 InnoDB) - -- 插入数据时,影响插入速度的主要是索引、唯一性校验、一次插入的数据条数等。 -- 开发环境情况下的考虑: - - 开发场景中,如果需要初始化数据,导入数据等一些操作,而且是开发人员进行处理的,可以考虑在插入数据之前,先禁用整张表的索引, - - 禁用索引使用 SQL:`ALTER TABLE table_name DISABLE KEYS;` - - 当导入完数据之后,重新让MySQL创建索引,并开启索引:`ALTER TABLE table_name ENABLE KEYS;` - - 如果表中有字段是有唯一性约束的,可以先禁用,然后在开启: - - 禁用唯一性检查的语句:`SET UNIQUE_CHECKS = 0;` - - 开启唯一性检查的语句:`SET UNIQUE_CHECKS = 1;` - - 禁用外键检查(建议还是少量用外键,而是采用代码逻辑来处理) - - 插入数据之前执行禁止对外键的检查,数据插入完成后再恢复,可以提供插入速度。 - - 禁用:`SET foreign_key_checks = 0;` - - 开启:`SET foreign_key_checks = 1;` - - 使用批量插入数据 - - 禁止自动提交 - - 插入数据之前执行禁止事务的自动提交,数据插入完成后再恢复,可以提供插入速度。 - - 禁用:`SET autocommit = 0;` - - 开启:`SET autocommit = 1;` - - - -## 服务器优化 - -- 好硬件大家都知道,这里没啥好说,如果是 MySQL 单独一台机子,那机子内存可以考虑分配 60%~70% 给 MySQL -- 通过优化 MySQL 的参数可以提高资源利用率,从而达到提高 MySQL 服务器性能的目的。 - - 可以看我整理的这篇文章: -- 由于 binlog 日志的读写频繁,可以考虑在 my.cnf 中配置,指定这个 binlog 日志到一个 SSD 硬盘上。 - -## 资料 - -- -- diff --git a/NTP.md b/NTP.md deleted file mode 100644 index 4ce9bb55..00000000 --- a/NTP.md +++ /dev/null @@ -1,43 +0,0 @@ -## NTP(Network Time Protocol)介绍 - - - -## NTP 安装 - -- 查看是否已安装: - - CentOS:`rpm -qa | grep ntp-*` - - Ubuntu:`dpkg -l | grep ntp-*` - -- 安装: - - CentOS 6:`sudo yum install -y ntp` - - Ubuntu:`sudo apt-get install -y ntp` - -## NTP 服务器配置文件常用参数 - -- 世界上可以校对时间节点: -- 中国时间校对服务器节点: -- 配置文件介绍(记得先备份):`sudo vim /etc/ntp.conf` - - ![NTP 服务器配置文件常用参数](images/NTP-a-1.jpg) - - 该配置解释: - - 标注 1 是默认内容,我们这里进行了注释。 - - 标注 2 是新增内容,表示使用中国时间校对服务器节点地址。 - ``` nginx - server 0.asia.pool.ntp.org - server 1.asia.pool.ntp.org - server 2.asia.pool.ntp.org - server 3.asia.pool.ntp.org - ``` -- 启动服务: - - `sudo service ntpd start` -- 服务加到启动项 - - CentOS 系统 - - `sudo chkconfig ntpd on` - - Ubuntu 系统 - - `sudo apt-get install -y sysv-rc-conf ` - - `sudo sysv-rc-conf ntpd on` - -## NTP 资料 - -- -- -- diff --git a/README.md b/README.md index f71a5d4a..80bf6ad0 100644 --- a/README.md +++ b/README.md @@ -1,127 +1,42 @@ -# Java 程序员眼中的 Linux + +## 作者新方向,感谢支持 + +- [从开公司到开发全平台产品(文字版)](https://github.com/cdk8s/cdk8s-team-style/blob/master/full-stack/README.md) +- [从开公司到开发全平台产品(视频版)](https://space.bilibili.com/1765486559/channel/seriesdetail?sid=2359281) ## 初衷(Original Intention) -- 整理下自己所学 +- 整理下自己所学。**但是比较随意,所以很多地方不够严谨,所以请带着批评的思维阅读。** - 带动更多的人进入 Linux 世界,特别是做 Java 开发的人 - Github 项目地址,欢迎 `Fork`、`Star`: - 文章中用到的一些安装包归纳整理: +- Gitbook 在线阅读地址: - **学得越多越是明白一个人的力量是不够的,我只是起了一个引子,希望你能一起参与,真心希望!!!(鞠躬)** -## 目录(Contents) - -- [Linux 介绍](Linux.md) -- [Ubuntu 介绍](Ubuntu.md) -- [Ubuntu 安装](Ubuntu-Install.md) -- [Ubuntu 设置(目录)](ubuntu-settings/ubuntu-settings-toc.md) -- [CentOS 介绍](CentOS.md) -- [CentOS 6 安装](CentOS-Install.md) -- [CentOS 7 安装](CentOS-7-Install.md) -- [CentOS 6 和 CentOS 7 差异](CentOS6-and-CentOS7.md) -- [CentOS 设置(目录)](centos-settings/centos-settings-toc.md) -- [Ubuntu 安装 VMware](Ubuntu-Install-VMware.md) -- [VMware 克隆 CentOS 后网卡信息修改](CentOS-Virtual-Machine-Copy-Settings.md) -- [Vim 安装、配置、快捷键列表](Vim-Install-And-Settings.md) -- [Bash 命令](Bash.md) -- [Bash 其他常用命令](Bash-Other-Bash.md) -- [Sed 命令](Sed.md) -- [Linux 下常用压缩文件的解压、压缩](File-Extract-Compress.md) -- [Yum 下载安装包及对应依赖包](Off-line-Yum-Install.md) -- [Zsh 入门](Zsh.md) -- [日常维护](maintenance.md) -- [nmon 系统性能监控工具](Nmon.md) -- [SSH(Secure Shell)介绍](SSH.md) -- [FTP(File Transfer Protocol)介绍](FTP.md) -- [VPN(Virtual Private Network)介绍](VPN.md) -- [NFS(Network FileSystem)介绍](NFS.md) -- [NTP(Network Time Protocol)介绍](NTP.md) -- [Samba 介绍](Samba.md) -- [Crontab 介绍](Crontab.md) -- [Iptables 介绍](Iptables.md) -- [花生壳-安装介绍](Hsk-Install.md) -- [JDK 安装](JDK-Install.md) -- [SVN 安装和配置](SVN-Install-And-Settings.md) -- [Tomcat 安装和配置、优化](Tomcat-Install-And-Settings.md) -- [Jenkins 安装和配置](Jenkins-Install-And-Settings.md) -- [Maven 安装和配置](Maven-Install-And-Settings.md) -- [Nexus 安装和配置](Nexus-Install-And-Settings.md) -- [MySQL 安装和配置](Mysql-Install-And-Settings.md) -- [MySQL 优化](Mysql-Optimize.md) -- [MySQL 测试](Mysql-Test.md) -- [MySQL 教程](Mysql-Tutorial.md) -- [Redis 安装和配置](Redis-Install-And-Settings.md) -- [MongoDB 安装和配置](MongoDB-Install-And-Settings.md) -- [Solr 安装和配置](Solr-Install-And-Settings.md) -- [Jira 安装和配置](Jira-Install-And-Settings.md) -- [Jenkins 安装和配置](Jenkins-Install-And-Settings.md) -- [TeamCity 安装和配置](TeamCity-Install-And-Settings.md) -- [Nginx 安装和配置](Nginx-Install-And-Settings.md) -- [FastDFS 安装和配置](FastDFS-Install-And-Settings.md) -- [FastDFS 结合 GraphicsMagick](FastDFS-Nginx-Lua-GraphicsMagick.md) -- [RabbitMQ 安装和配置](RabbitMQ-Install-And-Settings.md) -- [Openfire 安装和配置](Openfire-Install-And-Settings.md) -- [Rap 安装和配置](Rap-Install-And-Settings.md) -- [Nginx + Keepalived 高可用](Nginx-Keepalived-Install-And-Settings.md) -- [黑客入侵检查](Was-Hacked.md) -- [Shadowsocks 安装和配置](http://code.youmeek.com/2016/08/19/2016/08/VPS/) -- [Mycat 安装和配置](Mycat-Install-And-Settings.md) -- [Zookeeper 安装和配置](Zookeeper-Install.md) -- [Daemontools 工具介绍](Daemontools.md) -- [Tmux 安装和配置](Tmux-Install-And-Settings.md) -- [ELK 日志收集系统安装和配置](ELK-Install-And-Settings.md) -- [Dubbo 安装和配置](Dubbo-Install-And-Settings.md) -- [GitLab 安装和配置](Gitlab-Install-And-Settings.md) -- [Docker 安装和使用](Docker-Install-And-Usage.md) -- [LDAP 安装和使用](LDAP-Install-And-Settings.md) -- [Alfresco 安装和使用](Alfresco-Install-And-Usage.md) -- [Apache Thrift 安装和使用](Thrift-Install-And-Usage.md) -- [Node.js 安装和使用](Node-Install-And-Usage.md) - - -## 下一步(Next) - -- Apache 安装和配置 -- LVS + Keepalived 高可用 -- MySQL + Keepalived 高可用 -- ActiveMQ 服务安装和配置 -- Zabbix 安装和配置 -- Nagios 安装和配置 -- sed 学习 -- 常用脚本 - -## 联系(Contact) +## 优秀同行推荐 -- Email:judas.n@qq.com(常用) or admin@youmeek.com(备用) -- Blog: -- QQ 群交流,入群请看: -- 欢迎捐赠 ^_^: +- [Linux工具快速教程](http://linuxtools-rst.readthedocs.io/zh_CN/latest/base/index.html) +## 目录(Contents) -## Github 协同视频教程(Participate) - -- 如果您不会使用 Git 或是 Github 也没关系,请认真学习下面视频教程: -- Judas.n 录制 - - 视频格式:MP4 - - 分辨率:1920 X 1080 - - 片长:16 min - - 文件大小:62 M -- 下载 - - 百度云盘: - - 360 网盘(2fb5): - -## Github 常用按钮说明 - -- Watch:关注该项目,作者有更新的时候,会在你的 Github 主页有通知消息。 -- Star:收藏该项目,在你的头像上有一个“Your stars”链接,可以看到你的收藏列表。 -- Fork:复制一份项目到的Github空间上,你可以自己开发自己的这个地址项目,然后 Pull Request 给项目原主人。 - -## 参与作者汇总(Author) - -|作者(按参与时间排序)|地址| -|:---------|:---------| -|Judas.n|| -|nl101531|| - -## AD - -- [我个人开发的个性化定制网址导航:GitNavi.com](http://www.gitnavi.com) +- [Linux 介绍](markdown-file/Linux.md) +- [Ubuntu 介绍](markdown-file/Ubuntu.md) +- [Ubuntu 安装](markdown-file/Ubuntu-Install.md) +- [Ubuntu 设置(目录)](markdown-file/ubuntu-settings/ubuntu-settings-toc.md) +- [Kali Linux 介绍和设置(目录)](markdown-file/kali-linux-settings/kali-linux-toc.md) +- [CentOS 介绍](markdown-file/CentOS.md) +- [CentOS 6 安装](markdown-file/CentOS-Install.md) +- [CentOS 7 安装](markdown-file/CentOS-7-Install.md) +- [CentOS 6 和 CentOS 7 差异](markdown-file/CentOS6-and-CentOS7.md) +- [CentOS 设置(目录)](markdown-file/centos-settings/centos-settings-toc.md) +- [Ubuntu 安装 VMware](markdown-file/Ubuntu-Install-VMware.md) +- [VMware 克隆 CentOS 后网卡信息修改](markdown-file/CentOS-Virtual-Machine-Copy-Settings.md) +- [Vim 安装、配置、快捷键列表](markdown-file/Vim-Install-And-Settings.md) +- [SSH 免密登录](markdown-file/SSH-login-without-password.md) +- [Bash 命令](markdown-file/Bash.md) +- [Bash 其他常用命令](markdown-file/Bash-Other-Bash.md) +- [安装的 rm(删除)](markdown-file/shell-safe-rm.md) +- [Sed 命令](markdown-file/Sed.md) +- [Linux 下常用压缩文件的解压、压缩](markdown-file/File-Extract-Compress.md) +- [Yum 下载安装包及对应依赖包](markdown-file/Off-line-Yum-Install.md) +- [Zsh 入门](markdown-file/Zsh.md) diff --git a/RabbitMQ-Install-And-Settings.md b/RabbitMQ-Install-And-Settings.md deleted file mode 100644 index a0c46082..00000000 --- a/RabbitMQ-Install-And-Settings.md +++ /dev/null @@ -1,83 +0,0 @@ -# RabbitMQ 安装和配置 - - -## RabbitMQ 说明 - -- MQ 全称为 Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。 - - RabbitMQ 是一个在 AMQP 基础上完整的,可复用的企业消息系统。他遵循 Mozilla Public License 开源协议。 -- RabbitMQ WIKI: -- RabbitMQ 百科: -- RabbitMQ 官网: -- RabbitMQ 官网下载: -- RabbitMQ 官网安装文档: -- RabbitMQ 文档: - - 优先: - - 次要: - -## 基于 epel 源进行安装(优先) - -- 来源: - -``` -rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm - -# 安装依赖环境erlang -yum install erlang -y - -# 安装rabbitmq -yum install rabbitmq-server -y -``` - -## 本地安装 - -#### 本地安装 Erlang - -- 有 EPEL 源的情况(需要安装的内容较多,宽带要能跟上):`sudo yum install erlang` -- RabbitMQ 官网提供 Erlang 安装包: - - 下载地址: - - 下载好之后,安装下面两个文件: - - `sudo yum localinstall -y esl-erlang_18.1-1~centos~6_amd64.rpm` - - `sudo yum localinstall -y esl-erlang-compat-18.1-1.noarch.rpm` - - -#### rpm 安装 RabbitMQ - -- 此时(2016-04),最新版:**3.6.1** -- 安装:`rpm --import https://www.rabbitmq.com/rabbitmq-signing-key-public.asc` -- 安装:`sudo yum install -y rabbitmq-server-3.6.1-1.noarch.rpm` -- 启动服务: - - 先看下自己的主机名:`hostname`,我的主机名是:**judasnHost2** - - 先修改一下 host 文件:`vim /etc/hosts`,添加一行:`127.0.0.1 judasnHost2`(必须这样做) - - 启动:`service rabbitmq-server start`,启动一般都比较慢,所以别急 - - 停止:`service rabbitmq-server stop` - - 重启:`service rabbitmq-server restart` - - 设置开机启动:`chkconfig rabbitmq-server on` - - -## 配置 - -- 查找默认配置位置:`find / -name "rabbitmq.config.example"`,我这边搜索结果是:`/usr/share/doc/rabbitmq-server-3.6.1/rabbitmq.config.example` -- 复制默认配置:`cp /usr/share/doc/rabbitmq-server-3.6.1/rabbitmq.config.example /etc/rabbitmq/` -- 修改配置文件名:`cd /etc/rabbitmq ; mv rabbitmq.config.example rabbitmq.config` -- 编辑配置文件,开启用户远程访问:`vim rabbitmq.config` - - 在 64 行,默认有这样一句话:`%% {loopback_users, []},`,注意,该语句最后有一个逗号,等下是要去掉的 - - 我们需要改为:`{loopback_users, []}`, -- 开启 Web 界面管理:`rabbitmq-plugins enable rabbitmq_management` - - 如果你是用 epel 安装的话,则是这样运行:`cd /usr/lib/rabbitmq/bin;./rabbitmq-plugins enable rabbitmq_management` -- 重启 RabbitMQ 服务:`service rabbitmq-server restart` -- 开放防火墙端口: - - `sudo iptables -I INPUT -p tcp -m tcp --dport 15672 -j ACCEPT` - - `sudo iptables -I INPUT -p tcp -m tcp --dport 5672 -j ACCEPT` - - `sudo service iptables save` - - `sudo service iptables restart` -- 浏览器访问:`http://192.168.1.114:15672` - 默认管理员账号:**guest** - 默认管理员密码:**guest** -- 添加新授权用户(如下图所示): - - ![RabbitMQ-Add-User](images/RabbitMQ-Add-User-a-1.jpg) -- 添加 Host(如下图所示): - - ![RabbitMQ-Add-User](images/RabbitMQ-Add-User-a-2.jpg) -- 给添加的 Host 设置权限(如下图所示): - - ![RabbitMQ-Add-User](images/RabbitMQ-Add-User-a-3.gif) -- 交换机绑定队列(如下图所示): - - ![RabbitMQ-Bindings-Queue](images/RabbitMQ-Bindings-Queue-a-1.gif) diff --git a/SSH.md b/SSH.md deleted file mode 100644 index 32cd8f70..00000000 --- a/SSH.md +++ /dev/null @@ -1,86 +0,0 @@ -# SSH(Secure Shell)介绍 - - - -## SSH 安装 - -- 查看是否已安装: - - CentOS:`rpm -qa | grep openssh` - - Ubuntu:`dpkg -l | grep openssh` - -- 安装: - - CentOS 6:`sudo yum install -y openssh-server openssh-clients` - - Ubuntu:`sudo apt-get install -y openssh-server openssh-client` - - -## SSH 修改连接端口 - -- 配置文件介绍(记得先备份):`sudo vim /etc/ssh/sshd_config` -- 打开这一行注释:Port 22 - - 自定义端口选择建议在万位的端口,如:10000-65535之间,假设这里我改为 60001 -- 给新端口加到防火墙中: - - 添加规则:`iptables -I INPUT -p tcp -m tcp --dport 60001 -j ACCEPT` - - 保存规则:`service iptables save` - - 重启 iptables:`service iptables restart` - -## 设置超时 - -- ClientAliveInterval指定了服务器端向客户端请求消息的时间间隔, 默认是0,不发送。而ClientAliveInterval 300表示5分钟发送一次,然后客户端响应,这样就保持长连接了。 -- ClientAliveCountMax,默认值3。ClientAliveCountMax表示服务器发出请求后客户端没有响应的次数达到一定值,就自动断开,正常情况下,客户端不会不响应。 -- 正常我们可以设置为: - - ClientAliveInterval 300 - - ClientAliveCountMax 3 - - 按上面的配置的话,300*3=900秒=15分钟,即15分钟客户端不响应时,ssh连接会自动退出。 - -## SSH 允许 root 账户登录 - -- 编辑配置文件(记得先备份):`sudo vim /etc/ssh/sshd_config` - - 允许 root 账号登录 - - 注释掉:`PermitRootLogin without-password` - - 新增一行:`PermitRootLogin yes` - -## SSH 不允许 root 账户登录 - -- 新增用户和把新增的用户改为跟 root 同等权限方法:[Bash.md] -- 编辑配置文件(记得先备份):`sudo vim /etc/ssh/sshd_config` - - 注释掉这一句(如果没有这一句则不管它):`PermitRootLogin yes` - -## SSH 密钥登录 - -- 生成秘钥和公钥文件,命令:`sudo ssh-keygen`,在交互提示中连续按三次回车,如果看得懂交互的表达,那就根据你自己需求来。默认生成密钥和公钥文件是在:/root/.ssh。 -- 进入生成目录:`cd /root/.ssh`,可以看到有两个文件:id_rsa (私钥) 和 id_rsa.pub (公钥) -- 在 .ssh 目录下创建 SSH 认证文件,命令:`touch /root/.ssh/authorized_keys` -- 将公钥内容写到SSH认证文件里面,命令:`cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys` -- 修改SSH认证文件权限,命令: - - `sudo chmod 700 /root/.ssh` - - `sudo chmod 600 /root/.ssh/authorized_keys` -- 重启服务:`sudo service sshd restart` -- 设置 SSH 服务默认启动:`sudo sysv-rc-conf ssh on` -- 现在 SSH 客户端可以去拿着 SSH 服务器端上的 id_rsa,在客户端指定秘钥文件地址即可,这个一般由于你使用的客户端决定的,我这里推荐的是 Xshell 软件。 - -## 限制只有某一个IP才能远程登录服务器 - -- 在该配置文件:`vim /etc/hosts.deny` - - 添加该内容:`sshd:ALL` -- 在该配置文件:`vim /etc/hosts.allow` - - 添加该内容:`sshd:123.23.1.23` - -## 限制某些用户可以 SSH 访问 - -- 在该配置文件:`vim /etc/ssh/sshd_config` - - 添加该内容:`AllowUsers root userName1 userName2` - -## 修改完配置都要记得重启服务 - -- 命令:`service sshd restart` - -## 常用 SSH 连接终端 - -- Windows -- Xshell: -- Mac -- ZOC: - -## SSH 资料 - -- -- -- diff --git a/SUMMARY.md b/SUMMARY.md index dcfa3027..d034445b 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -1,66 +1,95 @@ # Java 程序员眼中的 Linux -* [Linux 介绍](Linux.md) -* [Ubuntu 介绍](Ubuntu.md) -* [Ubuntu 安装](Ubuntu-Install.md) -* [Ubuntu 设置(目录)](ubuntu-settings/ubuntu-settings-toc.md) -* [CentOS 介绍](CentOS.md) -* [CentOS 6 安装](CentOS-Install.md) -* [CentOS 7 安装](CentOS-7-Install.md) -* [CentOS 6 和 CentOS 7 差异](CentOS6-and-CentOS7.md) -* [CentOS 设置(目录)](centos-settings/centos-settings-toc.md) -* [Ubuntu 安装 VMware](Ubuntu-Install-VMware.md) -* [VMware 克隆 CentOS 后网卡信息修改](CentOS-Virtual-Machine-Copy-Settings.md) -* [Vim 安装、配置、快捷键列表](Vim-Install-And-Settings.md) -* [Bash 命令](Bash.md) -* [Bash 其他常用命令](Bash-Other-Bash.md) -* [Sed 命令](Sed.md) -* [Linux 下常用压缩文件的解压、压缩](File-Extract-Compress.md) -* [Yum 下载安装包及对应依赖包](Off-line-Yum-Install.md) -* [Zsh 入门](Zsh.md) -* [日常维护](maintenance.md) -* [nmon 系统性能监控工具](Nmon.md) -* [SSH(Secure Shell)介绍](SSH.md) -* [FTP(File Transfer Protocol)介绍](FTP.md) -* [VPN(Virtual Private Network)介绍](VPN.md) -* [NFS(Network FileSystem)介绍](NFS.md) -* [NTP(Network Time Protocol)介绍](NTP.md) -* [Samba 介绍](Samba.md) -* [Crontab 介绍](Crontab.md) -* [Iptables 介绍](Iptables.md) -* [花生壳-安装介绍](Hsk-Install.md) -* [JDK 安装](JDK-Install.md) -* [SVN 安装和配置](SVN-Install-And-Settings.md) -* [Tomcat 安装和配置、优化](Tomcat-Install-And-Settings.md) -* [Jenkins 安装和配置](Jenkins-Install-And-Settings.md) -* [Maven 安装和配置](Maven-Install-And-Settings.md) -* [Nexus 安装和配置](Nexus-Install-And-Settings.md) -* [MySQL 安装和配置](Mysql-Install-And-Settings.md) -* [MySQL 优化](Mysql-Optimize.md) -* [MySQL 测试](Mysql-Test.md) -* [MySQL 教程](Mysql-Tutorial.md) -* [Redis 安装和配置](Redis-Install-And-Settings.md) -* [MongoDB 安装和配置](MongoDB-Install-And-Settings.md) -* [Solr 安装和配置](Solr-Install-And-Settings.md) -* [Jira 安装和配置](Jira-Install-And-Settings.md) -* [Jenkins 安装和配置](Jenkins-Install-And-Settings.md) -* [TeamCity 安装和配置](TeamCity-Install-And-Settings.md) -* [Nginx 安装和配置](Nginx-Install-And-Settings.md) -* [FastDFS 安装和配置](FastDFS-Install-And-Settings.md) -* [FastDFS 结合 GraphicsMagick](FastDFS-Nginx-Lua-GraphicsMagick.md) -* [RabbitMQ 安装和配置](RabbitMQ-Install-And-Settings.md) -* [Openfire 安装和配置](Openfire-Install-And-Settings.md) -* [Rap 安装和配置](Rap-Install-And-Settings.md) -* [Nginx + Keepalived 高可用](Nginx-Keepalived-Install-And-Settings.md) -* [黑客入侵检查](Was-Hacked.md) -* [Shadowsocks 安装和配置](http://code.youmeek.com/2016/08/19/2016/08/VPS/) -* [Mycat 安装和配置](Mycat-Install-And-Settings.md) -* [Zookeeper 安装和配置](Zookeeper-Install.md) -* [Daemontools 工具介绍](Daemontools.md) -* [Tmux 安装和配置](Tmux-Install-And-Settings.md) -* [ELK 日志收集系统安装和配置](ELK-Install-And-Settings.md) -* [Dubbo 安装和配置](Dubbo-Install-And-Settings.md) -* [GitLab 安装和配置](Gitlab-Install-And-Settings.md) -* [Docker 安装和使用](Docker-Install-And-Usage.md) -* [LDAP 安装和使用](LDAP-Install-And-Settings.md) -* [Alfresco 安装和使用](Alfresco-Install-And-Usage.md) +* [Linux 介绍](markdown-file/Linux.md) +* [Ubuntu 介绍](markdown-file/Ubuntu.md) +* [Ubuntu 安装](markdown-file/Ubuntu-Install.md) +* [Ubuntu 设置(目录)](markdown-file/ubuntu-settings/ubuntu-settings-toc.md) +* [Kali Linux 介绍和设置(目录)](markdown-file/kali-linux-settings/kali-linux-toc.md) +* [CentOS 介绍](markdown-file/CentOS.md) +* [CentOS 6 安装](markdown-file/CentOS-Install.md) +* [CentOS 7 安装](markdown-file/CentOS-7-Install.md) +* [CentOS 6 和 CentOS 7 差异](markdown-file/CentOS6-and-CentOS7.md) +* [CentOS 设置(目录)](markdown-file/centos-settings/centos-settings-toc.md) +* [Ubuntu 安装 VMware](markdown-file/Ubuntu-Install-VMware.md) +* [VMware 克隆 CentOS 后网卡信息修改](markdown-file/CentOS-Virtual-Machine-Copy-Settings.md) +* [Vim 安装、配置、快捷键列表](markdown-file/Vim-Install-And-Settings.md) +* [SSH 免密登录](markdown-file/SSH-login-without-password.md) +* [Bash 命令](markdown-file/Bash.md) +* [Bash 其他常用命令](markdown-file/Bash-Other-Bash.md) +* [安装的 rm(删除)](markdown-file/shell-safe-rm.md) +* [Sed 命令](markdown-file/Sed.md) +* [Linux 下常用压缩文件的解压、压缩](markdown-file/File-Extract-Compress.md) +* [Yum 下载安装包及对应依赖包](markdown-file/Off-line-Yum-Install.md) +* [Zsh 入门](markdown-file/Zsh.md) +* [终端测速](markdown-file/speedtest.md) +* [日常维护](markdown-file/maintenance.md) +* [日常监控](markdown-file/monitor.md) +* [nmon 系统性能监控工具](markdown-file/Nmon.md) +* [Glances 安装和配置](markdown-file/Glances-Install-And-Settings.md) +* [SSH(Secure Shell)介绍](markdown-file/SSH.md) +* [FTP(File Transfer Protocol)介绍](markdown-file/FTP.md) +* [VPN(Virtual Private Network)介绍](markdown-file/VPN.md) +* [NFS(Network FileSystem)介绍](markdown-file/NFS.md) +* [NTP(Network Time Protocol)介绍](markdown-file/NTP.md) +* [Samba 介绍](markdown-file/Samba.md) +* [Crontab 介绍](markdown-file/Crontab.md) +* [Iptables 介绍](markdown-file/Iptables.md) +* [花生壳-安装介绍](markdown-file/Hsk-Install.md) +* [JDK 安装](markdown-file/JDK-Install.md) +* [Java bin 目录下的工具](markdown-file/Java-bin.md) +* [SVN 安装和配置](markdown-file/SVN-Install-And-Settings.md) +* [Tomcat 安装和配置、优化](markdown-file/Tomcat-Install-And-Settings.md) +* [Jenkins 安装和配置](markdown-file/Jenkins-Install-And-Settings.md) +* [Maven 安装和配置](markdown-file/Maven-Install-And-Settings.md) +* [Nexus 安装和配置](markdown-file/Nexus-Install-And-Settings.md) +* [PostgreSQL 安装和配置](markdown-file/PostgreSQL-Install-And-Settings.md) +* [MySQL 安装和配置](markdown-file/Mysql-Install-And-Settings.md) +* [MySQL 优化](markdown-file/Mysql-Optimize.md) +* [MySQL 测试](markdown-file/Mysql-Test.md) +* [MySQL 教程](markdown-file/Mysql-Tutorial.md) +* [Percona XtraDB Cluster(PXC)安装和配置](markdown-file/PXC-Install-And-Settings.md) +* [Redis 安装和配置](markdown-file/Redis-Install-And-Settings.md) +* [MongoDB 安装和配置](markdown-file/MongoDB-Install-And-Settings.md) +* [Solr 安装和配置](markdown-file/Solr-Install-And-Settings.md) +* [Jira 安装和配置](markdown-file/Jira-Install-And-Settings.md) +* [Confluence 安装和配置](markdown-file/Confluence-Install-And-Settings.md) +* [Jenkins 安装和配置](markdown-file/Jenkins-Install-And-Settings.md) +* [TeamCity 安装和配置](markdown-file/TeamCity-Install-And-Settings.md) +* [Nginx 安装和配置](markdown-file/Nginx-Install-And-Settings.md) +* [wrk 安装和配置](markdown-file/wrk-Install-And-Settings.md) +* [FastDFS 安装和配置](markdown-file/FastDFS-Install-And-Settings.md) +* [FastDFS 结合 GraphicsMagick](markdown-file/FastDFS-Nginx-Lua-GraphicsMagick.md) +* [RabbitMQ 安装和配置](markdown-file/RabbitMQ-Install-And-Settings.md) +* [Openfire 安装和配置](markdown-file/Openfire-Install-And-Settings.md) +* [Rap 安装和配置](markdown-file/Rap-Install-And-Settings.md) +* [Nginx + Keepalived 高可用](markdown-file/Nginx-Keepalived-Install-And-Settings.md) +* [黑客入侵检查](markdown-file/Was-Hacked.md) +* [Shadowsocks 安装和配置](markdown-file/http://code.youmeek.com/2016/08/19/2016/08/VPS/) +* [Mycat 安装和配置](markdown-file/Mycat-Install-And-Settings.md) +* [Zookeeper 安装和配置](markdown-file/Zookeeper-Install.md) +* [Daemontools 工具介绍](markdown-file/Daemontools.md) +* [Tmux 安装和配置](markdown-file/Tmux-Install-And-Settings.md) +* [ELK 日志收集系统安装和配置](markdown-file/ELK-Install-And-Settings.md) +* [Dubbo 安装和配置](markdown-file/Dubbo-Install-And-Settings.md) +* [GitLab 安装和配置](markdown-file/Gitlab-Install-And-Settings.md) +* [JMeter 安装和配置](markdown-file/JMeter-Install-And-Settings.md) +* [Docker 安装和使用](markdown-file/Docker-Install-And-Usage.md) +* [Harbor 安装和配置](markdown-file/Harbor-Install-And-Usage.md) +* [LDAP 安装和使用](markdown-file/LDAP-Install-And-Settings.md) +* [Alfresco 安装和使用](markdown-file/Alfresco-Install-And-Usage.md) +* [Apache Thrift 安装和使用](markdown-file/Thrift-Install-And-Usage.md) +* [Node.js 安装和使用](markdown-file/Node-Install-And-Usage.md) +* [CI 整套服务安装和使用](markdown-file/CI-Install-And-Usage.md) +* [YApi 安装和配置](markdown-file/YApi-Install-And-Settings.md) +* [Kafka 安装和配置](markdown-file/Kafka-Install-And-Settings.md) +* [Hadoop 安装和配置](markdown-file/Hadoop-Install-And-Settings.md) +* [Showdoc 安装和配置](markdown-file/Showdoc-Install-And-Settings.md) +* [WordPress 安装和配置](markdown-file/WordPress-Install-And-Settings.md) +* [GoAccess 安装和配置](markdown-file/GoAccess-Install-And-Settings.md) +* [Portainer 安装和配置](markdown-file/Portainer-Install-And-Settings.md) +* [Influxdb 安装和配置](markdown-file/Influxdb-Install-And-Settings.md) +* [Prometheus 安装和配置](markdown-file/Prometheus-Install-And-Settings.md) +* [Grafana 安装和配置](markdown-file/Grafana-Install-And-Settings.md) +* [Ansible 安装和配置](markdown-file/Ansible-Install-And-Settings.md) +* [Wormhole + Flink 安装和配置](markdown-file/Wormhole-Install-And-Settings.md) +* [SkyWalking 安装和配置](markdown-file/SkyWalking-Install-And-Settings.md) \ No newline at end of file diff --git a/Samba.md b/Samba.md deleted file mode 100644 index c684f630..00000000 --- a/Samba.md +++ /dev/null @@ -1,49 +0,0 @@ -# Samba 介绍 - - -## Samba 安装 - -- 查看是否已安装: - - CentOS:`rpm -qa | grep samba` - - Ubuntu:`dpkg -l | grep samba` - -- 安装: - - CentOS 6:`XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX` - - Ubuntu:`sudo apt-get install -y samba samba-client` - -## Samba 服务器配置文件常用参数 - -- 配置文件介绍(记得先备份):`sudo vim /etc/samba/smb.conf` - - 该配置解释: - - 在 [globle] 区域 - - workgroup = WORKGROUP #WORKGROUP表示Windows默认的工作组名称,一般共享给windows是设置为WORKGROUP - - security = user #ubuntu下配置文件默认没有这句,这个是自己填上去的。表示指定samba的安全等级,安全等级分别有四种:share(其他人不需要账号密码即可访问共享目录)、user(检查账号密码)、server(表示检查密码由另外一台服务器负责)、domain(指定Windows域控制服务器来验证用户的账号和密码) - - 在新区域区域 - - 当 security = share 使用下面这段,这段自己添加的,其中myshare这个名字表示其他机子访问该分享地址时用:file://该服务机IP/myshare - ``` - [myshare] - comment = share all - path = /opt/mysamba #分享的目录,其中这个目录需要chmod 777 /opt/mysamba权限 - browseable = yes - writable = yes - public =yes - ``` - - 当 security = user 使用下面这段,这段自己添加的,其中 myshare2 这个名字表示其他机子访问该分享地址时用:file://该服务机IP/myshare2 - - 可以返回的账号必须是系统已经存在的账号。先给系统添加账号:`useradd user1`,再用samba的设置添加账号:`pdbedit -a user1`,会让你设立该samba账号密码。列出账号:`pdbedit -L` - ``` - [myshare2] - comment = share for users - path = /opt/mysamba2 #分享的目录,其中这个目录需要chmod 777 /opt/mysamba权限 - browseable = yes - writable = yes - public = no - ``` -- 启动服务: - - `sudo service samba restart` - -## Samba 资料 - -- -- -- -- diff --git a/TOC.md b/TOC.md index 3304bd73..434c20f7 100644 --- a/TOC.md +++ b/TOC.md @@ -1,50 +1,92 @@ -- [Linux 介绍](Linux.md) -- [Ubuntu 介绍](Ubuntu.md) -- [Ubuntu 安装](Ubuntu-Install.md) -- [Ubuntu 设置(目录)](ubuntu-settings/ubuntu-settings-toc.md) -- [CentOS 介绍](CentOS.md) -- [CentOS 安装](CentOS-Install.md) -- [CentOS 设置(目录)](centos-settings/centos-settings-toc.md) -- [Ubuntu 安装 VMware](Ubuntu-Install-VMware.md) -- [VMware 克隆 CentOS 后网卡信息修改](CentOS-Virtual-Machine-Copy-Settings.md) -- [Vim 安装、配置、快捷键列表](Vim-Install-And-Settings.md) -- [Bash 命令](Bash.md) -- [Bash 其他常用命令](Bash-Other-Bash.md) -- [Linux 下常用压缩文件的解压、压缩](File-Extract-Compress.md) -- [Yum 下载安装包及对应依赖包](Off-line-Yum-Install.md) -- [Zsh 入门](Zsh.md) -- [日常维护](maintenance.md) -- [nmon 系统性能监控工具](Nmon.md) -- [SSH(Secure Shell)介绍](SSH.md) -- [FTP(File Transfer Protocol)介绍](FTP.md) -- [VPN(Virtual Private Network)介绍](VPN.md) -- [NFS(Network FileSystem)介绍](NFS.md) -- [NTP(Network Time Protocol)介绍](NTP.md) -- [Samba 介绍](Samba.md) -- [Crontab 介绍](Crontab.md) -- [Iptables 介绍](Iptables.md) -- [花生壳-安装介绍](Hsk-Install.md) -- [JDK 安装](JDK-Install.md) -- [SVN 安装和配置](SVN-Install-And-Settings.md) -- [Tomcat 安装和配置、优化](Tomcat-Install-And-Settings.md) -- [Jenkins 安装和配置](Jenkins-Install-And-Settings.md) -- [Maven 安装和配置](Maven-Install-And-Settings.md) -- [Nexus 安装和配置](Nexus-Install-And-Settings.md) -- [MySQL 安装和配置](Mysql-Install-And-Settings.md) -- [MySQL 优化](Mysql-Optimize.md) -- [MySQL 教程](Mysql-Tutorial.md) -- [Redis 安装和配置](Redis-Install-And-Settings.md) -- [Solr 安装和配置](Solr-Install-And-Settings.md) -- [Jira 安装和配置](Jira-Install-And-Settings.md) -- [Jenkins 安装和配置](Jenkins-Install-And-Settings.md) -- [TeamCity 安装和配置](TeamCity-Install-And-Settings.md) -- [Nginx 安装和配置](Nginx-Install-And-Settings.md) -- [FastDFS 安装和配置](FastDFS-Install-And-Settings.md) -- [FastDFS 结合 GraphicsMagick](FastDFS-Nginx-Lua-GraphicsMagick.md) -- [RabbitMQ 安装和配置](RabbitMQ-Install-And-Settings.md) -- [Openfire 安装和配置](Openfire-Install-And-Settings.md) -- [Rap 安装和配置](Rap-Install-And-Settings.md) -- [Nginx + Keepalived 高可用](Nginx-Keepalived-Install-And-Settings.md) -- [黑客入侵检查](Was-Hacked.md) -- [Shadowsocks 安装和配置](http://code.youmeek.com/2016/08/19/2016/08/VPS/) -- [Mycat 安装和配置](Mycat-Install-And-Settings.md) \ No newline at end of file +- [Linux 介绍](markdown-file/Linux.md) +- [Ubuntu 介绍](markdown-file/Ubuntu.md) +- [Ubuntu 安装](markdown-file/Ubuntu-Install.md) +- [Ubuntu 设置(目录)](markdown-file/ubuntu-settings/ubuntu-settings-toc.md) +- [Kali Linux 介绍和设置(目录)](markdown-file/kali-linux-settings/kali-linux-toc.md) +- [CentOS 介绍](markdown-file/CentOS.md) +- [CentOS 6 安装](markdown-file/CentOS-Install.md) +- [CentOS 7 安装](markdown-file/CentOS-7-Install.md) +- [CentOS 6 和 CentOS 7 差异](markdown-file/CentOS6-and-CentOS7.md) +- [CentOS 设置(目录)](markdown-file/centos-settings/centos-settings-toc.md) +- [Ubuntu 安装 VMware](markdown-file/Ubuntu-Install-VMware.md) +- [VMware 克隆 CentOS 后网卡信息修改](markdown-file/CentOS-Virtual-Machine-Copy-Settings.md) +- [Vim 安装、配置、快捷键列表](markdown-file/Vim-Install-And-Settings.md) +- [SSH 免密登录](markdown-file/SSH-login-without-password.md) +- [Bash 命令](markdown-file/Bash.md) +- [Bash 其他常用命令](markdown-file/Bash-Other-Bash.md) +- [安装的 rm(删除)](markdown-file/shell-safe-rm.md) +- [Sed 命令](markdown-file/Sed.md) +- [Linux 下常用压缩文件的解压、压缩](markdown-file/File-Extract-Compress.md) +- [Yum 下载安装包及对应依赖包](markdown-file/Off-line-Yum-Install.md) +- [Zsh 入门](markdown-file/Zsh.md) +- [终端测速](markdown-file/speedtest.md) +- [日常维护](markdown-file/maintenance.md) +- [日常监控](markdown-file/monitor.md) +- [nmon 系统性能监控工具](markdown-file/Nmon.md) +- [Glances 安装和配置](markdown-file/Glances-Install-And-Settings.md) +- [SSH(Secure Shell)介绍](markdown-file/SSH.md) +- [FTP(File Transfer Protocol)介绍](markdown-file/FTP.md) +- [VPN(Virtual Private Network)介绍](markdown-file/VPN.md) +- [NFS(Network FileSystem)介绍](markdown-file/NFS.md) +- [NTP(Network Time Protocol)介绍](markdown-file/NTP.md) +- [Samba 介绍](markdown-file/Samba.md) +- [Crontab 介绍](markdown-file/Crontab.md) +- [Iptables 介绍](markdown-file/Iptables.md) +- [花生壳-安装介绍](markdown-file/Hsk-Install.md) +- [JDK 安装](markdown-file/JDK-Install.md) +- [Java bin 目录下的工具](markdown-file/Java-bin.md) +- [SVN 安装和配置](markdown-file/SVN-Install-And-Settings.md) +- [Tomcat 安装和配置、优化](markdown-file/Tomcat-Install-And-Settings.md) +- [Jenkins 安装和配置](markdown-file/Jenkins-Install-And-Settings.md) +- [Maven 安装和配置](markdown-file/Maven-Install-And-Settings.md) +- [Nexus 安装和配置](markdown-file/Nexus-Install-And-Settings.md) +- [PostgreSQL 安装和配置](markdown-file/PostgreSQL-Install-And-Settings.md) +- [MySQL 安装和配置](markdown-file/Mysql-Install-And-Settings.md) +- [MySQL 优化](markdown-file/Mysql-Optimize.md) +- [MySQL 测试](markdown-file/Mysql-Test.md) +- [MySQL 教程](markdown-file/Mysql-Tutorial.md) +- [Percona XtraDB Cluster(PXC)安装和配置](markdown-file/PXC-Install-And-Settings.md) +- [Redis 安装和配置](markdown-file/Redis-Install-And-Settings.md) +- [MongoDB 安装和配置](markdown-file/MongoDB-Install-And-Settings.md) +- [Solr 安装和配置](markdown-file/Solr-Install-And-Settings.md) +- [Jira 安装和配置](markdown-file/Jira-Install-And-Settings.md) +- [Confluence 安装和配置](markdown-file/Confluence-Install-And-Settings.md) +- [Jenkins 安装和配置](markdown-file/Jenkins-Install-And-Settings.md) +- [TeamCity 安装和配置](markdown-file/TeamCity-Install-And-Settings.md) +- [Nginx 安装和配置](markdown-file/Nginx-Install-And-Settings.md) +- [wrk 安装和配置](markdown-file/wrk-Install-And-Settings.md) +- [FastDFS 安装和配置](markdown-file/FastDFS-Install-And-Settings.md) +- [FastDFS 结合 GraphicsMagick](markdown-file/FastDFS-Nginx-Lua-GraphicsMagick.md) +- [RabbitMQ 安装和配置](markdown-file/RabbitMQ-Install-And-Settings.md) +- [Openfire 安装和配置](markdown-file/Openfire-Install-And-Settings.md) +- [Rap 安装和配置](markdown-file/Rap-Install-And-Settings.md) +- [Nginx + Keepalived 高可用](markdown-file/Nginx-Keepalived-Install-And-Settings.md) +- [黑客入侵检查](markdown-file/Was-Hacked.md) +- [Shadowsocks 安装和配置](markdown-file/http://code.youmeek.com/2016/08/19/2016/08/VPS/) +- [Mycat 安装和配置](markdown-file/Mycat-Install-And-Settings.md) +- [Zookeeper 安装和配置](markdown-file/Zookeeper-Install.md) +- [Daemontools 工具介绍](markdown-file/Daemontools.md) +- [Tmux 安装和配置](markdown-file/Tmux-Install-And-Settings.md) +- [ELK 日志收集系统安装和配置](markdown-file/ELK-Install-And-Settings.md) +- [Dubbo 安装和配置](markdown-file/Dubbo-Install-And-Settings.md) +- [GitLab 安装和配置](markdown-file/Gitlab-Install-And-Settings.md) +- [JMeter 安装和配置](markdown-file/JMeter-Install-And-Settings.md) +- [Docker 安装和使用](markdown-file/Docker-Install-And-Usage.md) +- [Harbor 安装和配置](markdown-file/Harbor-Install-And-Usage.md) +- [LDAP 安装和使用](markdown-file/LDAP-Install-And-Settings.md) +- [Alfresco 安装和使用](markdown-file/Alfresco-Install-And-Usage.md) +- [Apache Thrift 安装和使用](markdown-file/Thrift-Install-And-Usage.md) +- [Node.js 安装和使用](markdown-file/Node-Install-And-Usage.md) +- [YApi 安装和配置](markdown-file/YApi-Install-And-Settings.md) +- [Kafka 安装和配置](markdown-file/Kafka-Install-And-Settings.md) +- [Hadoop 安装和配置](markdown-file/Hadoop-Install-And-Settings.md) +- [Showdoc 安装和配置](markdown-file/Showdoc-Install-And-Settings.md) +- [WordPress 安装和配置](markdown-file/WordPress-Install-And-Settings.md) +- [GoAccess 安装和配置](markdown-file/GoAccess-Install-And-Settings.md) +- [Portainer 安装和配置](markdown-file/Portainer-Install-And-Settings.md) +- [Influxdb 安装和配置](markdown-file/Influxdb-Install-And-Settings.md) +- [Prometheus 安装和配置](markdown-file/Prometheus-Install-And-Settings.md) +- [Grafana 安装和配置](markdown-file/Grafana-Install-And-Settings.md) +- [Ansible 安装和配置](markdown-file/Ansible-Install-And-Settings.md) +- [Wormhole + Flink 安装和配置](markdown-file/Wormhole-Install-And-Settings.md) +- [SkyWalking 安装和配置](markdown-file/SkyWalking-Install-And-Settings.md) \ No newline at end of file diff --git a/Zookeeper-Install.md b/Zookeeper-Install.md deleted file mode 100644 index d7adbd08..00000000 --- a/Zookeeper-Install.md +++ /dev/null @@ -1,66 +0,0 @@ -# Zookeeper 安装 - - -## 需要环境 - -- JDK 安装 - -## 下载安装 - -- 官网: -- 此时(201702)最新稳定版本:Release `3.4.9` -- 官网下载: -- 我这里以:`zookeeper-3.4.8.tar.gz` 为例 -- 安装过程: - - `mkdir -p /usr/program/zookeeper/data` - - `cd /opt/setups` - - `tar zxvf zookeeper-3.4.8.tar.gz` - - `mv /opt/setups/zookeeper-3.4.8 /usr/program/zookeeper` - - `cd /usr/program/zookeeper/zookeeper-3.4.8/conf` - - `mv zoo_sample.cfg zoo.cfg` - - `vim zoo.cfg` -- 将配置文件中的这个值: - - 原值:`dataDir=/tmp/zookeeper` - - 改为:`dataDir=/usr/program/zookeeper/data` -- 防火墙开放2181端口 - - `iptables -A INPUT -p tcp -m tcp --dport 2181 -j ACCEPT` - - `service iptables save` - - `service iptables restart` -- 启动 zookeeper:`sh /usr/program/zookeeper/zookeeper-3.4.8/bin/zkServer.sh start` -- 停止 zookeeper:`sh /usr/program/zookeeper/zookeeper-3.4.8/bin/zkServer.sh stop` -- 查看 zookeeper 状态:`sh /usr/program/zookeeper/zookeeper-3.4.8/bin/zkServer.sh status` - - 如果是集群环境,下面几种角色 - - leader - - follower - -## 集群环境搭建 - -### 确定机子环境 - -- 集群环境最少节点是:3,且节点数必须是奇数,生产环境推荐是:5 个机子节点。 -- 系统都是 CentOS 6 -- 机子 1:192.168.1.121 -- 机子 2:192.168.1.111 -- 机子 3:192.168.1.112 - -### 配置 - -- 在三台机子上都做如上文的流程安装,再补充修改配置文件:`vim /usr/program/zookeeper/zookeeper-3.4.8/conf/zoo.cfg` -- 三台机子都增加下面内容: - -``` nginx -server.1=192.168.1.121:2888:3888 -server.2=192.168.1.111:2888:3888 -server.3=192.168.1.112:2888:3888 -``` - -- 在 机子 1 增加一个该文件:`vim /usr/program/zookeeper/data/myid`,文件内容填写:`1` -- 在 机子 2 增加一个该文件:`vim /usr/program/zookeeper/data/myid`,文件内容填写:`2` -- 在 机子 3 增加一个该文件:`vim /usr/program/zookeeper/data/myid`,文件内容填写:`3` -- 然后在三台机子上都启动 zookeeper:`sh /usr/program/zookeeper/zookeeper-3.4.8/bin/zkServer.sh start` -- 分别查看三台机子的状态:`sh /usr/program/zookeeper/zookeeper-3.4.8/bin/zkServer.sh status`,应该会得到类似这样的结果: - -``` -Using config: /usr/program/zookeeper/zookeeper-3.4.8/bin/../conf/zoo.cfg -Mode: follower 或者 Mode: leader -``` diff --git a/centos-settings/CentOS-Extra-Packages.md b/centos-settings/CentOS-Extra-Packages.md index def938fe..c00901e3 100644 --- a/centos-settings/CentOS-Extra-Packages.md +++ b/centos-settings/CentOS-Extra-Packages.md @@ -83,6 +83,22 @@ - `sudo yum install -y htop`(htop 官方源是没有的,所以如果能下载下来就表示已经使用了第三方源) +### 禁用源 + +- 编辑:`vim /etc/yum.repos.d/elasticsearch.repo` +- 把 enabled=1 改为 enabled=0 + +``` +[elasticsearch-6.x] +name=Elasticsearch repository for 6.x packages +baseurl=https://artifacts.elastic.co/packages/6.x/yum +gpgcheck=1 +gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch +enabled=1 +autorefresh=1 +type=rpm-md +``` + > 资料: - diff --git a/centos-settings/CentOS-Network-Settings.md b/centos-settings/CentOS-Network-Settings.md index d94b28ef..ba95ede9 100644 --- a/centos-settings/CentOS-Network-Settings.md +++ b/centos-settings/CentOS-Network-Settings.md @@ -44,19 +44,22 @@ ``` - 重启网络配置:`service network restart` -## CentOS 7 +## CentOS 7.x ### 命令行下设置网络 - 查看系统下有哪些网卡:`ls /etc/sysconfig/network-scripts/`,新版本不叫 eth0 这类格式了,比如我当前这个叫做:ifcfg-ens33(你的肯定跟我不一样,但是格式类似) +- 先备份:`cp /etc/sysconfig/network-scripts/ifcfg-ens33 /etc/sysconfig/network-scripts/ifcfg-ens33.bak` - 编辑该文件:`vim /etc/sysconfig/network-scripts/ifcfg-ens33`,改为如下信息:(IP 段自己改为自己的网络情况) ``` ini TYPE=Ethernet +PROXY_METHOD=none +BROWSER_ONLY=no BOOTPROTO=static -IPADDR=192.168.1.126 +IPADDR=192.168.0.127 NETMASK=255.255.255.0 -GATEWAY=192.168.1.1 +GATEWAY=192.168.0.1 DNS1=8.8.8.8 DNS1=114.114.114.114 DEFROUTE=yes @@ -71,7 +74,7 @@ IPV6_PEERROUTES=yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy NAME=ens33 -UUID=15a16b51-0369-44d7-87b4-667f715a68df +UUID=b9f01b7d-4ebf-4d3a-a4ec-ae203425bb11 DEVICE=ens33 ONBOOT=yes ``` diff --git a/centos-settings/Close-XWindow.md b/centos-settings/Close-XWindow.md index 0a34275f..5b89f556 100644 --- a/centos-settings/Close-XWindow.md +++ b/centos-settings/Close-XWindow.md @@ -15,7 +15,14 @@ - 在图形界面中如果你希望临时关闭图形界面可以输入:`init 3` -## CentOS 7 设置方法 +## CentOS 7 设置方法 1 + +- 开机以命令模式启动,执行: + - systemctl set-default multi-user.target +- 开机以图形界面启动,执行: + - systemctl set-default graphical.target + +## CentOS 7 设置方法 2 - 关闭图形 - `mv /etc/systemd/system/default.target /etc/systemd/system/default.target.bak` (改名备份) diff --git a/centos-settings/Cpu-Info.md b/centos-settings/Cpu-Info.md deleted file mode 100644 index fb653ca6..00000000 --- a/centos-settings/Cpu-Info.md +++ /dev/null @@ -1,22 +0,0 @@ -## CPU 信息分析 - - -## 初衷 - -- 了解服务器的性能,以方便我们如何更好地对程序进行部署 - - -## CPU 信息 - -- Demo CPU 型号:[Intel® Xeon® Processor E5-2620 v2(15M Cache, 2.10 GHz)](http://ark.intel.com/products/75789/Intel-Xeon-Processor-E5-2620-v2-15M-Cache-2_10-GHz) -- 该 CPU 显示的数据中有一项这个要注意:`Intel® Hyper-Threading Technology` 是 `Yes`。表示该 CPU 支持超线程 -- `cat /proc/cpuinfo`,查看 CPU 总体信息 -- `grep 'physical id' /proc/cpuinfo | sort -u | wc -l`,查看物理 CPU 个数 - - 结果:2 - - 物理 CPU:物理 CPU 也就是机器外面就能看到的一个个 CPU,每个物理 CPU 还带有单独的风扇 -- `grep 'core id' /proc/cpuinfo | sort -u | wc -l`,查看每个物理 CPU 的核心数量 - - 结果:6,因为每个物理 CPU 是 6,所有 2 个物理 CPU 的总核心数量应该是:12 - - 核心数:一个核心就是一个物理线程,英特尔有个超线程技术可以把一个物理线程模拟出两个线程来用,充分发挥 CPU 性能,意思是一个核心可以有多个线程。 -- `grep 'processor' /proc/cpuinfo | sort -u | wc -l`,查看 CPU 总的线程数,一般也叫做:逻辑 CPU 数量 - - 结果:24,正常情况下:CPU 的总核心数量 == CPU 线程数,但是如果该 CPU 支持超线程,那结果是:CPU 的总核心数量 X 2 == CPU 线程数 - - 线程数:线程数是一种逻辑的概念,简单地说,就是模拟出的 CPU 核心数。比如,可以通过一个 CPU 核心数模拟出 2 线程的 CPU,也就是说,这个单核心的 CPU 被模拟成了一个类似双核心 CPU 的功能。 diff --git a/centos-settings/centos-settings-toc.md b/centos-settings/centos-settings-toc.md index 4c05b3d8..4f73b884 100644 --- a/centos-settings/centos-settings-toc.md +++ b/centos-settings/centos-settings-toc.md @@ -1,7 +1,6 @@ - [CentOS 网络设置](CentOS-Network-Settings.md) - [CentOS 源设置](CentOS-Extra-Packages.md) - [CentOS 图形界面的关闭与开启](Close-XWindow.md) -- [CPU 信息分析](Cpu-Info.md) - [清除系统缓存](Clear-Cache.md) - [修改定时清理 /tmp 目录下的文件](Clear-Tmp-Directory.md) diff --git a/favorite-file/Nginx-Settings/nginx-front.conf b/favorite-file/Nginx-Settings/nginx-front.conf new file mode 100644 index 00000000..8b49d8f9 --- /dev/null +++ b/favorite-file/Nginx-Settings/nginx-front.conf @@ -0,0 +1,116 @@ +user root; +worker_processes auto; +pid /run/nginx.pid; + +events { + use epoll; + multi_accept on; + worker_connections 1024; +} + +http { + # 必须加这两个,不然 CSS 无法正常加载 + include mime.types; + default_type application/octet-stream; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for" "$request_time"'; + + access_log /var/log/nginx/access.log main; + error_log /var/log/nginx/error.log; + + gzip on; + gzip_buffers 8 16k; + gzip_min_length 512; + gzip_disable "MSIE [1-6]\.(?!.*SV1)"; + gzip_http_version 1.1; + gzip_types text/plain text/css application/javascript application/x-javascript application/json application/xml; + + server { + + listen 8001; + server_name localhost 127.0.0.1 139.159.190.24 platform.gitnavi.com; + + location / { + root /root/.jenkins/workspace/nestle-platform-front-test/dist; + index index.html index.htm; + try_files $uri /index.html; + } + + ## 二级目录方式,记得 package.json 添加:"homepage": "cdk8s-markdown", + location ^~ /cdk8s-markdown { + root /root/.jenkins/workspace; + index index.html; + try_files $uri /cdk8s-markdown/index.html; + } + + location ^~ /platform/ { + proxy_pass http://127.0.0.1:28081; + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location ~ .*\.(js|css)?$ { + root /root/.jenkins/workspace/nestle-platform-front-test/dist; + } + + location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ico|woff|woff2|ttf|eot|txt|svg)$ { + root /root/.jenkins/workspace/nestle-platform-front-test/dist; + } + + error_page 404 /404.html; + location = /usr/share/nginx/html/40x.html { + } + + error_page 500 502 503 504 /50x.html; + location = /usr/share/nginx/html/50x.html { + } + + } + + server { + + listen 8002; + server_name localhost 127.0.0.1 139.159.190.24 store.gitnavi.com; + + location / { + root /root/.jenkins/workspace/nestle-store-front-test/dist; + index index.html index.htm; + try_files $uri /index.html; + } + + location ^~ /store/ { + proxy_pass http://127.0.0.1:28082; + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location ~ .*\.(js|css)?$ { + root /root/.jenkins/workspace/nestle-store-front-test/dist; + } + + location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ico|woff|woff2|ttf|eot|txt|svg)$ { + root /root/.jenkins/workspace/nestle-store-front-test/dist; + } + + error_page 404 /404.html; + location = /usr/share/nginx/html/40x.html { + } + + error_page 500 502 503 504 /50x.html; + location = /usr/share/nginx/html/50x.html { + } + + } +} diff --git a/favorite-file/Nginx-Settings/nginx.conf b/favorite-file/Nginx-Settings/nginx.conf deleted file mode 100644 index 490367d2..00000000 --- a/favorite-file/Nginx-Settings/nginx.conf +++ /dev/null @@ -1,134 +0,0 @@ -user root; - -worker_processes 2;#Nginx进程数, 建议设置为等于CPU总核心数 - -events { - use epoll; #nginx工作模式,epoll是linux平台下的高效模式,配合nginx的异步非阻塞作用 - worker_connections 1024;#单个进程最大连接数 -} - -http { - include mime.types;#扩展名与文件类型映射表:#nginx通过服务端文件的后缀名来判断这个文件属于什么类型,再将该数据类型写入http头部的Content-Type字段中,发送给客户端。mime.types这个文件里面全是文件类型的定义。 - default_type application/octet-stream;#当用户请求的文件后缀在mime.types这个文件没有定义,便使用默认的type为二进制流 - sendfile on;#开启高效文件传输模式 - tcp_nopush on;#启用之后,数据包会累积到一定大小才会发送,减小了额外开销,防止网络阻塞,提高网络效率 - tcp_nodelay on;#启用之后,尽快发送数据。可以看到tcp_nopush是要等数据包累积到一定大小才发送,tcp_nodelay是要尽快发送,二者相互矛盾。实际上,它们可以一起用,最终的效果是先填满包,再尽快发送。 - keepalive_timeout 65; - charset utf8; - - #全局日志(也可以把这个配置到 server 中进行不同 server 的不同配置) - access_log /var/log/nginx/access.log; - error_log /var/log/nginx/error.log; - - # gzip 压缩设置 - gzip on; - gzip_min_length 1k; - gzip_buffers 4 16k; - gzip_http_version 1.0; - gzip_comp_level 2;#gzip的压缩程度,级别为1到9.级别越高,压缩程序越高,时间越多 - gzip_types text/plain application/x-javascript text/css text/xml application/xml text/javascript application/javascript application/json; - gzip_vary on;#告诉接受方数据经过gzip压缩 - gzip_disable "MSIE[1-6]\."; #因为IE6对gzip不支持,所以在IE6及更旧的版本不使用gzip压缩 - - server { - - listen 80; #监听80端口 - server_name localhost 127.0.0.1 120.77.84.121 gitnavi.com; - - location / { - root /usr/program/tomcat8/webapps/ROOT;#静态文件直接读取硬盘,所有这里直接写tomcat的程序里面的静态资源目录 - index index.html index.jsp; - } - - location = / { - root /usr/program/tomcat8/webapps/ROOT;#静态文件直接读取硬盘,所有这里直接写tomcat的程序里面的静态资源目录 - index index.html; - } - - # 匹配用户导航静态 html 目录路径 - location ^~ /u/ { - root /usr/program/tomcat8/webapps/ROOT;#静态文件直接读取硬盘,所有这里直接写tomcat的程序里面的静态资源目录 - } - - # Controller 中前台的请求标识 - location ^~ /front/ { - proxy_pass http://127.0.0.1:8080; #转发请求交给tomcat处理 - proxy_redirect off; - proxy_set_header Host $host; #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - client_max_body_size 10m; #允许客户端请求的最大单文件字节数 - client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数 - proxy_connect_timeout 300; #nginx跟后端服务器连接超时时间 - proxy_send_timeout 300; #后端服务器数据回传时间(代理发送超时) - proxy_read_timeout 300; #连接成功后,后端服务器响应时间 - proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小 - proxy_buffers 6 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置 - proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2) - proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传 - } - - # Controller 中后台的请求标识 - location ^~ /admin/ { - proxy_pass http://127.0.0.1:8080; #转发请求交给tomcat处理 - proxy_redirect off; - proxy_set_header Host $host; #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - client_max_body_size 10m; #允许客户端请求的最大单文件字节数 - client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数 - proxy_connect_timeout 300; #nginx跟后端服务器连接超时时间 - proxy_send_timeout 300; #后端服务器数据回传时间(代理发送超时) - proxy_read_timeout 300; #连接成功后,后端服务器响应时间 - proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小 - proxy_buffers 6 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置 - proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2) - proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传 - } - - #静态资源转发 - #由nginx处理静态页面 - location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ico|woff|woff2|ttf|eot)$ { - root /usr/program/tomcat8/webapps/ROOT;#这里直接写tomcat的程序里面的静态资源目录 - expires 30d;#使用expires缓存模块,缓存到客户端30天(这个模块看下有没有安装) - } - #因为我的 html 页面经常变动,所以 html 我这里就不缓存了 - location ~ .*\.(js|css)?$ { - root /usr/program/tomcat8/webapps/ROOT;#静态文件直接读取硬盘,所有这里直接写tomcat的程序里面的静态资源目录 - expires 1d;#也可以指定小时,比如:12h - } - # 读取一些静态页面,比如隐私政策等 - location ~ .*\.(html|htm)?$ { - root /usr/program/tomcat8/webapps/ROOT;#静态文件直接读取硬盘,所有这里直接写tomcat的程序里面的静态资源目录 - expires 1d;#也可以指定小时,比如:12h - } - - #其他请求都视为动态请求处理 - #location ~ .*$ { - # proxy_pass http://127.0.0.1:8080; #转发请求交给tomcat处理 - # proxy_redirect off; - # proxy_set_header Host $host; #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP - # proxy_set_header X-Real-IP $remote_addr; - # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # client_max_body_size 10m; #允许客户端请求的最大单文件字节数 - # client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数 - # proxy_connect_timeout 300; #nginx跟后端服务器连接超时时间 - # proxy_send_timeout 300; #后端服务器数据回传时间(代理发送超时) - # proxy_read_timeout 300; #连接成功后,后端服务器响应时间 - # proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小 - # proxy_buffers 6 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置 - # proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2) - # proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传 - #} - - #常见错误页面设置 - error_page 404 /404.html; - location = /404.html { - root /usr/program/tomcat8/webapps/ROOT; - } - error_page 500 502 503 504 /500.html; - location = /500.html { - root /usr/program/tomcat8/webapps/ROOT; - } - } -} diff --git a/favorite-file/gravitee-docker-compose/README.md b/favorite-file/gravitee-docker-compose/README.md new file mode 100644 index 00000000..e4983ec9 --- /dev/null +++ b/favorite-file/gravitee-docker-compose/README.md @@ -0,0 +1,32 @@ +# graviteeio api gateway docker-compose running + +fork from graviteeio project && change some deps image + +- +- + +## how to run + +```code +cd platform && docker-compose up -d +``` + +## manager ui + +* api portal + +```code +open https://localhost/apim/portal +``` + +* access manager ui + +```code +open https://localhost/am/ui/ +``` + +## Note: + +- environments directory has some demos with ci && traefik gateway +- portal account admin amdin +- access manager ui account admin adminadmin \ No newline at end of file diff --git a/favorite-file/gravitee-docker-compose/environments/ci/docker-compose.yml b/favorite-file/gravitee-docker-compose/environments/ci/docker-compose.yml new file mode 100644 index 00000000..37c9c07c --- /dev/null +++ b/favorite-file/gravitee-docker-compose/environments/ci/docker-compose.yml @@ -0,0 +1,62 @@ +#------------------------------------------------------------------------------- +# Copyright (C) 2015 The Gravitee team (http://gravitee.io) +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------- +version: '2' + +services: + ci: + image: graviteeio/jenkins:latest + container_name: ci + network_mode: "bridge" + expose: + - 50022 + ports: + - "50022:50022" + labels: + - "traefik.frontend.rule=Host:ci.gravitee.io" + - "traefik.port=8080" + volumes: + - /var/jenkins_home:/var/jenkins_home + - /var/run/docker.sock:/var/run/docker.sock + links: + - redis-test + - qa + + redis-test: + image: redis:3 + container_name: redis-test + network_mode: "bridge" + + qa: + image: sonarqube:alpine + container_name: qa + network_mode: "bridge" + environment: + - SONARQUBE_JDBC_URL=jdbc:postgresql://sonarqube-db:5432/sonar + labels: + - "traefik.frontend.rule=Host:qa.gravitee.io" + volumes: + - /opt/sonarqube/conf:/opt/sonarqube/conf + - /opt/sonarqube/data:/opt/sonarqube/data + - /opt/sonarqube/extensions:/opt/sonarqube/extensions + - /opt/sonarqube/bundled-plugins:/opt/sonarqube/lib/bundled-plugins + links: + - sonarqube-db + + sonarqube-db: + image: postgres:alpine + network_mode: "bridge" + environment: + - POSTGRES_USER=sonar + - POSTGRES_PASSWORD=sonar + volumes: + - /opt/sonarqube/postgresql/data:/var/lib/postgresql/data diff --git a/favorite-file/gravitee-docker-compose/environments/demo/common.yml b/favorite-file/gravitee-docker-compose/environments/demo/common.yml new file mode 100644 index 00000000..a1d7c696 --- /dev/null +++ b/favorite-file/gravitee-docker-compose/environments/demo/common.yml @@ -0,0 +1,62 @@ +#------------------------------------------------------------------------------- +# Copyright (C) 2015 The Gravitee team (http://gravitee.io) +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------- +version: '2' + +volumes: + datamongo: {} + dataelasticsearch: {} + +services: + elasticsearch: + hostname: demo-elasticsearch + image: docker.elastic.co/elasticsearch/elasticsearch:5.4.3 + volumes: + - dataelasticsearch:/usr/share/elasticsearch/data + environment: + - http.host=0.0.0.0 + - transport.host=0.0.0.0 + - xpack.security.enabled=false + - xpack.monitoring.enabled=false + - cluster.name=elasticsearch + - bootstrap.memory_lock=true + - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + ulimits: + memlock: + soft: -1 + hard: -1 + nofile: 65536 + + mongodb: + hostname: demo-mongodb + image: mongo:3.4 + volumes: + - datamongo:/data/db + + gateway: + hostname: demo-gateway + image: graviteeio/gateway:latest + environment: + - gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_ratelimit_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_reporters_elasticsearch_endpoints_0=http://elasticsearch:9200 + + managementui: + hostname: demo-managementui + image: graviteeio/management-ui:latest + + managementapi: + hostname: demo-managementapi + image: graviteeio/management-api:latest + environment: + - gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_analytics_elasticsearch_endpoints_0=http://elasticsearch:9200 diff --git a/favorite-file/gravitee-docker-compose/environments/demo/docker-compose-local.yml b/favorite-file/gravitee-docker-compose/environments/demo/docker-compose-local.yml new file mode 100644 index 00000000..38c34e4c --- /dev/null +++ b/favorite-file/gravitee-docker-compose/environments/demo/docker-compose-local.yml @@ -0,0 +1,76 @@ +#------------------------------------------------------------------------------- +# Copyright (C) 2015 The Gravitee team (http://gravitee.io) +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------- +version: '2' + +volumes: + local_datamongo: {} + local_dataelasticsearch: {} + +services: + local_elasticsearch: + extends: + file: common.yml + service: elasticsearch + volumes: + - local_dataelasticsearch:/usr/share/elasticsearch/data + - ./logs/elasticsearch:/var/log/elasticsearch + + local_mongodb: + extends: + file: common.yml + service: mongodb + volumes: + - local_datamongo:/data/db + - ./logs/mongodb:/var/log/mongodb + + local_gateway: + extends: + file: common.yml + service: gateway + links: + - "local_mongodb:demo-mongodb" + - "local_elasticsearch:demo-elasticsearch" + ports: + - "8000:8082" + volumes: + - ./logs/gateway:/etc/gravitee.io/log + environment: + - gravitee_management_mongodb_uri=mongodb://demo-mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_ratelimit_mongodb_uri=mongodb://demo-mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_reporters_elasticsearch_endpoints_0=http://demo-elasticsearch:9200 + + local_managementui: + extends: + file: common.yml + service: managementui + ports: + - "8002:80" + volumes: + - ./logs/management-ui:/var/log/httpd + environment: + - MGMT_API_URL=http:\/\/localhost:8005\/management\/ + + local_managementapi: + extends: + file: common.yml + service: managementapi + ports: + - "8005:8083" + volumes: + - ./logs/management-api:/home/gravitee/logs + links: + - "local_mongodb:demo-mongodb" + - "local_elasticsearch:demo-elasticsearch" + environment: + - gravitee_management_mongodb_uri=mongodb://demo-mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_analytics_elasticsearch_endpoints_0=http://demo-elasticsearch:9200 diff --git a/favorite-file/gravitee-docker-compose/environments/demo/docker-compose-traefik-latest.yml b/favorite-file/gravitee-docker-compose/environments/demo/docker-compose-traefik-latest.yml new file mode 100644 index 00000000..e3ea6bce --- /dev/null +++ b/favorite-file/gravitee-docker-compose/environments/demo/docker-compose-traefik-latest.yml @@ -0,0 +1,76 @@ +#------------------------------------------------------------------------------- +# Copyright (C) 2015 The Gravitee team (http://gravitee.io) +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------- +version: '2' + +volumes: + latest_datamongo: {} + latest_dataelasticsearch: {} + +services: + latest_elasticsearch: + network_mode: "bridge" + extends: + file: common.yml + service: elasticsearch + volumes: + - latest_dataelasticsearch:/usr/share/elasticsearch/data + + latest_mongodb: + network_mode: "bridge" + extends: + file: common.yml + service: mongodb + volumes: + - latest_datamongo:/data/db + + latest_gateway: + network_mode: "bridge" + extends: + file: common.yml + service: gateway + links: + - latest_mongodb + - latest_elasticsearch + labels: + - "traefik.backend=graviteeio-gateway" + - "traefik.frontend.rule=Host:demo.gravitee.io;PathPrefixStrip:/gateway" + environment: + - gravitee_management_mongodb_uri=mongodb://demo-mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_ratelimit_mongodb_uri=mongodb://demo-mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_reporters_elasticsearch_endpoints_0=http://demo-elasticsearch:9200 + + latest_managementui: + network_mode: "bridge" + extends: + file: common.yml + service: managementui + labels: + - "traefik.backend=graviteeio-managementui" + - "traefik.frontend.rule=Host:demo.gravitee.io" + environment: + - MGMT_API_URL=https:\/\/demo.gravitee.io\/management\/ + + latest_managementapi: + network_mode: "bridge" + extends: + file: common.yml + service: managementapi + labels: + - "traefik.backend=graviteeio-managementapi" + - "traefik.frontend.rule=Host:demo.gravitee.io;PathPrefix:/management" + links: + - latest_mongodb + - latest_elasticsearch + environment: + - gravitee_management_mongodb_uri=mongodb://demo-mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_analytics_elasticsearch_endpoints_0=http://demo-elasticsearch:9200 \ No newline at end of file diff --git a/favorite-file/gravitee-docker-compose/environments/demo/docker-compose-traefik-nightly.yml b/favorite-file/gravitee-docker-compose/environments/demo/docker-compose-traefik-nightly.yml new file mode 100644 index 00000000..2369851c --- /dev/null +++ b/favorite-file/gravitee-docker-compose/environments/demo/docker-compose-traefik-nightly.yml @@ -0,0 +1,79 @@ +#------------------------------------------------------------------------------- +# Copyright (C) 2015 The Gravitee team (http://gravitee.io) +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------- +version: '2' + +volumes: + nightly_datamongo: {} + nightly_dataelasticsearch: {} + +services: + nightly_elasticsearch: + network_mode: "bridge" + extends: + file: common.yml + service: elasticsearch + volumes: + - nightly_dataelasticsearch:/usr/share/elasticsearch/data + + nightly_mongodb: + network_mode: "bridge" + extends: + file: common.yml + service: mongodb + volumes: + - nightly_datamongo:/data/db + + nightly_gateway: + image: graviteeio/gateway:nightly + network_mode: "bridge" + extends: + file: common.yml + service: gateway + links: + - nightly_mongodb + - nightly_elasticsearch + labels: + - "traefik.backend=nightly-graviteeio-gateway" + - "traefik.frontend.rule=Host:nightly.gravitee.io;PathPrefixStrip:/gateway" + environment: + - gravitee_management_mongodb_uri=mongodb://demo-mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_ratelimit_mongodb_uri=mongodb://demo-mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_reporters_elasticsearch_endpoints_0=http://demo-elasticsearch:9200 + + nightly_managementui: + image: graviteeio/management-ui:nightly + network_mode: "bridge" + extends: + file: common.yml + service: managementui + labels: + - "traefik.backend=nightly-graviteeio-managementui" + - "traefik.frontend.rule=Host:nightly.gravitee.io" + environment: + - MGMT_API_URL=https:\/\/nightly.gravitee.io\/management\/ + + nightly_managementapi: + image: graviteeio/management-api:nightly + network_mode: "bridge" + extends: + file: common.yml + service: managementapi + labels: + - "traefik.backend=nightly-graviteeio-managementapi" + - "traefik.frontend.rule=Host:nightly.gravitee.io;PathPrefix:/management" + links: + - nightly_mongodb + - nightly_elasticsearch + environment: + - gravitee_management_mongodb_uri=mongodb://demo-mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_analytics_elasticsearch_endpoints_0=http://demo-elasticsearch:9200 \ No newline at end of file diff --git a/favorite-file/gravitee-docker-compose/environments/demo/launch.sh b/favorite-file/gravitee-docker-compose/environments/demo/launch.sh new file mode 100755 index 00000000..ff51ff04 --- /dev/null +++ b/favorite-file/gravitee-docker-compose/environments/demo/launch.sh @@ -0,0 +1,91 @@ +#!/bin/bash +#------------------------------------------------------------------------------- +# Copyright (C) 2015 The Gravitee team (http://gravitee.io) +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------- + +readonly WORKDIR="$HOME/graviteeio-demo" +readonly DIRNAME=`dirname $0` +readonly PROGNAME=`basename $0` +readonly color_title='\033[32m' +readonly color_text='\033[1;36m' + +# OS specific support (must be 'true' or 'false'). +declare cygwin=false +declare darwin=false +declare linux=false +declare dc_exec="docker-compose -f docker-compose-local.yml up" + +welcome() { + echo + echo -e " ${color_title} _____ _____ __ _______ _______ ______ ______ _____ ____ \033[0m" + echo -e " ${color_title} / ____| __ \ /\ \ / /_ _|__ __| ____| ____| |_ _/ __ \ \033[0m" + echo -e " ${color_title}| | __| |__) | / \ \ / / | | | | | |__ | |__ | || | | | \033[0m" + echo -e " ${color_title}| | |_ | _ / / /\ \ \/ / | | | | | __| | __| | || | | | \033[0m" + echo -e " ${color_title}| |__| | | \ \ / ____ \ / _| |_ | | | |____| |____ _ _| || |__| | \033[0m" + echo -e " ${color_title} \_____|_| \_\/_/ \_\/ |_____| |_| |______|______(_)_____\____/ \033[0m" + echo -e " ${color_title} | | \033[0m${color_text}http://gravitee.io\033[0m" + echo -e " ${color_title} __| | ___ _ __ ___ ___ \033[0m" + echo -e " ${color_title} / _\` |/ _ \ '_ \` _ \ / _ \ \033[0m" + echo -e " ${color_title}| (_| | __/ | | | | | (_) | \033[0m" + echo -e " ${color_title} \__,_|\___|_| |_| |_|\___/ \033[0m" + echo +} + +init_env() { + local dockergrp + # define env + case "`uname`" in + CYGWIN*) + cygwin=true + ;; + + Darwin*) + darwin=true + ;; + + Linux) + linux=true + ;; + esac + + # test if docker must be run with sudo + dockergrp=$(groups | grep -c docker) + if [[ $darwin == false && $dockergrp == 0 ]]; then + dc_exec="sudo $dc_exec"; + fi +} + +init_dirs() { + echo "Init log directory in $WORKDIR ..." + mkdir -p "$WORKDIR/logs/" + echo +} + +main() { + welcome + init_env + if [[ $? != 0 ]]; then + exit 1 + fi + set -e + init_dirs + pushd $WORKDIR > /dev/null + echo "Download docker compose files ..." + curl -L https://raw.githubusercontent.com/gravitee-io/gravitee-docker/master/environments/demo/common.yml -o "common.yml" + curl -L https://raw.githubusercontent.com/gravitee-io/gravitee-docker/master/environments/demo/docker-compose-local.yml -o "docker-compose-local.yml" + echo + echo "Launch GraviteeIO demo ..." + $dc_exec + popd > /dev/null +} + +main diff --git a/favorite-file/gravitee-docker-compose/environments/sample-apis/docker-compose-sample-apis.yml b/favorite-file/gravitee-docker-compose/environments/sample-apis/docker-compose-sample-apis.yml new file mode 100644 index 00000000..10c1a074 --- /dev/null +++ b/favorite-file/gravitee-docker-compose/environments/sample-apis/docker-compose-sample-apis.yml @@ -0,0 +1,47 @@ +#------------------------------------------------------------------------------- +# Copyright (C) 2015 The Gravitee team (http://gravitee.io) +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------- +version: '2' + +services: + + sample-api-index: + image: graviteeio/gravitee-sample-index:latest + network_mode: "bridge" + labels: + - "traefik.backend=gravitee-sample-index" + - "traefik.frontend.rule=Host:api.gravitee.io" + - "traefik.frontend.entryPoints=https" + + sample-api-echo: + image: graviteeio/gravitee-echo-api:nightly + network_mode: "bridge" + labels: + - "traefik.backend=gravitee-echo-api" + - "traefik.frontend.rule=Host:api.gravitee.io;PathPrefix:/echo" + - "traefik.frontend.entryPoints=https" + + sample-api-whoami: + image: graviteeio/gravitee-whoami-api:latest + network_mode: "bridge" + labels: + - "traefik.backend=gravitee-whoami-api" + - "traefik.frontend.rule=Host:api.gravitee.io;PathPrefix:/whoami" + - "traefik.frontend.entryPoints=https" + + sample-api-whattimeisit: + image: graviteeio/gravitee-whattimeisit-api:latest + network_mode: "bridge" + labels: + - "traefik.backend=gravitee-whattimeisit-api" + - "traefik.frontend.rule=Host:api.gravitee.io;PathPrefix:/whattimeisit" + - "traefik.frontend.entryPoints=https" diff --git a/favorite-file/gravitee-docker-compose/platform/docker-compose.yml b/favorite-file/gravitee-docker-compose/platform/docker-compose.yml new file mode 100644 index 00000000..3771102c --- /dev/null +++ b/favorite-file/gravitee-docker-compose/platform/docker-compose.yml @@ -0,0 +1,135 @@ +version: '3' + +networks: + default: + +services: + nginx: + image: nginx:1.15-alpine + container_name: gio_platform_nginx + volumes: + - ./nginx/nginx.conf:/etc/nginx/nginx.conf + - ./nginx/ssl/gio-selfsigned.crt:/etc/ssl/certs/gio-selfsigned.crt + - ./nginx/ssl/gio-selfsigned.key:/etc/ssl/private/gio-selfsigned.key + - ./nginx/ssl/gio.pem:/etc/ssl/certs/gio.pem + ports: + - "80:80" + - "443:443" + depends_on: + - apim_gateway + - apim_portal + - apim_management + - am_gateway + - am_management + - am_webui + + mongodb: + image: mongo:3.4 + container_name: gio_platform_mongo + ports: + - 27017:27017 + environment: + - MONGO_INITDB_DATABASE=gravitee + volumes: + - ./mongo/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d + - ./data/mongo:/data/db + - ./logs/mongodb:/var/log/mongodb + + elasticsearch: + image: elasticsearch:6.4.0 + container_name: gio_platform_elasticsearch + ports: + - 9200:9200 + environment: + - http.host=0.0.0.0 + - transport.host=0.0.0.0 + - xpack.security.enabled=false + - xpack.monitoring.enabled=false + - cluster.name=elasticsearch + ulimits: + nofile: 65536 + volumes: + - ./data/elasticsearch:/usr/share/elasticsearch/data + - ./logs/elasticsearch:/var/log/elasticsearch + + apim_gateway: + image: graviteeio/gateway:latest + container_name: gio_platform_apim_gateway + volumes: + - ./logs/apim-gateway:/opt/graviteeio-gateway/logs + environment: + - gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_ratelimit_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_reporters_elasticsearch_endpoints_0=http://elasticsearch:9200 + - gravitee_services_metrics_enabled=true + - gravitee_services_metrics_prometheus.enabled=true + depends_on: + - mongodb + - elasticsearch + + apim_portal: + image: graviteeio/management-ui:latest + container_name: gio_platform_apim_portal + environment: + - MGMT_API_URL=https:\/\/localhost\/apim\/management\/ + depends_on: + - apim_management + + apim_management: + image: graviteeio/management-api:latest + container_name: gio_platform_apim_mgmt_api + volumes: + - ./logs/apim-management-api:/opt/graviteeio-management-api/logs + environment: + - gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_ratelimit_mongodb_uri=mongodb://mongodb:27017/gravitee?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_analytics_elasticsearch_endpoints_0=http://elasticsearch:9200 + - gravitee_jwt_cookiepath=/apim/management + - gravitee_jwt_cookiesecure=true + depends_on: + - mongodb + - elasticsearch + + am_gateway: + image: graviteeio/am-gateway:2 + container_name: gio_platform_am_gateway + volumes: + - ./logs/am-gateway:/opt/graviteeio-am-gateway/logs + environment: + - gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee-am?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_oauth2_mongodb_uri=mongodb://mongodb:27017/gravitee-am?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + depends_on: + - mongodb + + am_management: + image: graviteeio/am-management-api:2 + container_name: gio_platform_am_management + volumes: + - ./logs/am-management-api:/opt/graviteeio-am-management-api/logs + environment: + - gravitee_management_mongodb_uri=mongodb://mongodb:27017/gravitee-am?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_oauth2_mongodb_uri=mongodb://mongodb:27017/gravitee-am?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000&socketTimeoutMS=5000 + - gravitee_jwt_cookiepath=/am/management + - gravitee_jwt_cookiesecure=true + depends_on: + - mongodb + grafana: + image: grafana/grafana + ports: + - "3000:3000" + prometheus: + image: prom/prometheus + volumes: + - "./prometheus.yml:/etc/prometheus/prometheus.yml" + ports: + - "9090:9090" + am_webui: + image: graviteeio/am-management-ui:2 + container_name: gio_platform_am_webui + environment: + - MGMT_API_URL=https:\/\/localhost\/am\/ + - MGMT_UI_URL=https:\/\/localhost\/am\/ui\/ + volumes: + - ./logs/am-webui:/var/log/nginx + depends_on: + - am_management diff --git a/favorite-file/gravitee-docker-compose/platform/mongo/docker-entrypoint-initdb.d/create-index.js b/favorite-file/gravitee-docker-compose/platform/mongo/docker-entrypoint-initdb.d/create-index.js new file mode 100644 index 00000000..b6f2d379 --- /dev/null +++ b/favorite-file/gravitee-docker-compose/platform/mongo/docker-entrypoint-initdb.d/create-index.js @@ -0,0 +1,92 @@ + +// "apis" collection +db.apis.dropIndexes(); +db.apis.createIndex( { "visibility" : 1 } ); +db.apis.createIndex( { "group" : 1 } ); +db.apis.reIndex(); + +// "applications" collection +db.applications.dropIndexes(); +db.applications.createIndex( { "group" : 1 } ); +db.applications.createIndex( { "name" : 1 } ); +db.applications.createIndex( { "status" : 1 } ); +db.applications.reIndex(); + +// "events" collection +db.events.dropIndexes(); +db.events.createIndex( { "type" : 1 } ); +db.events.createIndex( { "updatedAt" : 1 } ); +db.events.createIndex( { "properties.api_id" : 1 } ); +db.events.createIndex( { "properties.api_id":1, "type":1} ); +db.events.reIndex(); + +// "plans" collection +db.plans.dropIndexes(); +db.plans.createIndex( { "apis" : 1 } ); +db.plans.reIndex(); + +// "subscriptions" collection +db.subscriptions.dropIndexes(); +db.subscriptions.createIndex( { "plan" : 1 } ); +db.subscriptions.createIndex( { "application" : 1 } ); +db.subscriptions.reIndex(); + +// "keys" collection +db.keys.dropIndexes(); +db.keys.createIndex( { "plan" : 1 } ); +db.keys.createIndex( { "application" : 1 } ); +db.keys.createIndex( { "updatedAt" : 1 } ); +db.keys.createIndex( { "revoked" : 1 } ); +db.keys.createIndex( { "plan" : 1 , "revoked" : 1, "updatedAt" : 1 } ); +db.keys.reIndex(); + +// "pages" collection +db.pages.dropIndexes(); +db.pages.createIndex( { "api" : 1 } ); +db.pages.reIndex(); + +// "memberships" collection +db.memberships.dropIndexes(); +db.memberships.createIndex( {"_id.userId":1, "_id.referenceId":1, "_id.referenceType":1}, { unique: true } ); +db.memberships.createIndex( {"_id.referenceId":1, "_id.referenceType":1} ); +db.memberships.createIndex( {"_id.referenceId":1, "_id.referenceType":1, "roles":1} ); +db.memberships.createIndex( {"_id.userId":1, "_id.referenceType":1} ); +db.memberships.createIndex( {"_id.userId":1, "_id.referenceType":1, "roles":1} ); +db.memberships.reIndex(); + +// "roles" collection +db.roles.dropIndexes(); +db.roles.createIndex( {"_id.scope": 1 } ); +db.roles.reIndex(); + +// "audits" collection +db.audits.dropIndexes(); +db.audits.createIndex( { "referenceType": 1, "referenceId": 1 } ); +db.audits.createIndex( { "createdAt": 1 } ); +db.audits.reIndex(); + +// "rating" collection +db.rating.dropIndexes(); +db.rating.createIndex( { "api" : 1 } ); +db.rating.reIndex(); + +// "ratingAnswers" collection +db.ratingAnswers.dropIndexes(); +db.ratingAnswers.createIndex( { "rating" : 1 } ); + +// "portalnotifications" collection +db.portalnotifications.dropIndexes(); +db.portalnotifications.createIndex( { "user" : 1 } ); +db.portalnotifications.reIndex(); + +// "portalnotificationconfigs" collection +db.portalnotificationconfigs.dropIndexes(); +db.portalnotificationconfigs.createIndex( {"_id.user":1, "_id.referenceId":1, "_id.referenceType":1}, { unique: true } ); +db.portalnotificationconfigs.createIndex( {"_id.referenceId":1, "_id.referenceType":1, "hooks":1}); +db.portalnotificationconfigs.reIndex(); + +// "genericnotificationconfigs" collection +db.genericnotificationconfigs.dropIndexes(); +db.genericnotificationconfigs.createIndex( {"referenceId":1, "referenceType":1, "hooks":1}); +db.genericnotificationconfigs.createIndex( {"referenceId":1, "referenceType":1}); +db.genericnotificationconfigs.reIndex(); diff --git a/favorite-file/gravitee-docker-compose/platform/nginx/nginx.conf b/favorite-file/gravitee-docker-compose/platform/nginx/nginx.conf new file mode 100644 index 00000000..d08fc26c --- /dev/null +++ b/favorite-file/gravitee-docker-compose/platform/nginx/nginx.conf @@ -0,0 +1,133 @@ +worker_processes 4; + +events { worker_connections 1024; } + +http { + include /etc/nginx/mime.types; + resolver 127.0.0.11 ipv6=off; + + upstream apim_management { + server apim_management:8083; + } + + upstream apim_gateway { + server apim_gateway:8082; + } + + upstream apim_portal { + server apim_portal:80; + } + + upstream am_management { + server am_management:8093; + } + + upstream am_gateway { + server am_gateway:8092; + } + + upstream am_webui { + server am_webui:80; + } + + server { + listen 80; + server_name localhost; + return 301 https://$server_name$request_uri; #Redirection + } + + server { + listen 443 ssl; + listen [::]:443 ssl; + + server_name localhost; + + ssl_certificate /etc/ssl/certs/gio-selfsigned.crt; + ssl_certificate_key /etc/ssl/private/gio-selfsigned.key; + ssl_dhparam /etc/ssl/certs/gio.pem; + + error_page 500 502 503 504 /50x.html; + + location /apim/portal/ { + proxy_pass http://apim_portal/; + proxy_redirect $scheme://$host:$server_port/ $scheme://$http_host/apim/portal/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $server_name; + } + + location /apim/management/ { + proxy_pass http://apim_management/management/; + proxy_redirect $scheme://$host:$server_port/management/ /apim/management/; + sub_filter "/management/" "/apim/management/"; + sub_filter_types application/json; + sub_filter_once off; + proxy_cookie_path /management /apim/management; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $server_name; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /apim/ { + proxy_pass http://apim_gateway/; + proxy_cookie_path / /apim; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $server_name; + } + + location /am/ui/ { + proxy_pass http://am_webui/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $server_name; + sub_filter ' ~/.vimrc - diff --git a/favorite-file/shell/crontab-redis-restart.sh b/favorite-file/shell/crontab-redis-restart.sh new file mode 100644 index 00000000..b566416c --- /dev/null +++ b/favorite-file/shell/crontab-redis-restart.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +redis-cli -h 127.0.0.1 -p 6379 -a 123456789 shutdown + +sleep 5s + +/usr/local/bin/redis-server /etc/redis.conf + + diff --git a/favorite-file/shell/crontab-test.sh b/favorite-file/shell/crontab-test.sh new file mode 100644 index 00000000..8490bbeb --- /dev/null +++ b/favorite-file/shell/crontab-test.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +time1=$(date "+%Y-%m-%d %H:%M:%S") + +echo "${time1}" >> /opt/1.txt + +sleep 5s + +time2=$(date "+%Y-%m-%d %H:%M:%S") + +echo "${time2}" >> /opt/1.txt diff --git a/favorite-file/shell/install_common_tool_CentOS.sh b/favorite-file/shell/install_common_tool_CentOS.sh new file mode 100644 index 00000000..541da34f --- /dev/null +++ b/favorite-file/shell/install_common_tool_CentOS.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +echo "开始常用工具安装" + +yum install -y zip unzip lrzsz git epel-release wget htop deltarpm + +echo "开始常用工具结束" \ No newline at end of file diff --git a/favorite-file/shell/auto_install_common_tool.sh b/favorite-file/shell/install_common_tool_ubuntu.sh similarity index 55% rename from favorite-file/shell/auto_install_common_tool.sh rename to favorite-file/shell/install_common_tool_ubuntu.sh index 0e7a333a..3d808206 100644 --- a/favorite-file/shell/auto_install_common_tool.sh +++ b/favorite-file/shell/install_common_tool_ubuntu.sh @@ -2,6 +2,6 @@ echo "开始常用工具安装" -yum install -y zip unzip lrzsz +sudo apt-get install -y zip unzip unrar lrzsz git wget htop echo "开始常用工具结束" \ No newline at end of file diff --git a/favorite-file/shell/install_common_vim.sh b/favorite-file/shell/install_common_vim.sh new file mode 100644 index 00000000..3c8b1e1f --- /dev/null +++ b/favorite-file/shell/install_common_vim.sh @@ -0,0 +1,12 @@ +#!/bin/sh + + +echo "-----------------------------------------开始常用工具安装" +yum install -y zip unzip lrzsz git epel-release + +echo "-----------------------------------------开始安装 vim" +yum install -y vim + +echo "-----------------------------------------设置 vim 配置" +curl https://raw.githubusercontent.com/wklken/vim-for-server/master/vimrc > ~/.vimrc + diff --git a/favorite-file/shell/install_common_vim_zsh.sh b/favorite-file/shell/install_common_vim_zsh.sh new file mode 100644 index 00000000..64e4f1c1 --- /dev/null +++ b/favorite-file/shell/install_common_vim_zsh.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +echo "-----------------------------------------禁用防火墙" +systemctl stop firewalld.service +systemctl disable firewalld.service + +echo "-----------------------------------------开始常用工具安装" +yum install -y zip unzip lrzsz git epel-release + +echo "-----------------------------------------开始常用工具结束" +echo "-----------------------------------------开始安装 zsh" +yum install -y zsh + +echo "-----------------------------------------开始安装 oh-my-zsh" +wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O - | sh + +echo "-----------------------------------------设置默认终端为 oh-my-zsh" +chsh -s /bin/zsh root + + +echo "-----------------------------------------开始安装 vim" +yum install -y vim + +echo "-----------------------------------------设置 vim 配置" +curl https://raw.githubusercontent.com/wklken/vim-for-server/master/vimrc > ~/.vimrc + diff --git a/favorite-file/shell/install_docker_centos7.sh b/favorite-file/shell/install_docker_centos7.sh new file mode 100644 index 00000000..fe8e8550 --- /dev/null +++ b/favorite-file/shell/install_docker_centos7.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +echo "安装 docker 所需环境" + +yum install -y yum-utils device-mapper-persistent-data lvm2 + +echo "添加 repo(可能网络会很慢,有时候会报:Timeout,所以要多试几次)" + +yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo +yum makecache fast + +echo "开始安装 docker" + +yum install -y docker-ce + +echo "启动 Docker" + +systemctl start docker.service + +echo "安装结束" + +echo "运行 hello world 镜像" + +docker run hello-world + + +echo "安装 docker compose" + +curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose + +chmod +x /usr/local/bin/docker-compose + +echo "输出 docker compose 版本号" + +docker-compose --version +systemctl restart docker.service +systemctl enable docker.service \ No newline at end of file diff --git a/favorite-file/shell/install_docker_disable_firewalld_centos7-aliyun.sh b/favorite-file/shell/install_docker_disable_firewalld_centos7-aliyun.sh new file mode 100644 index 00000000..587ca77b --- /dev/null +++ b/favorite-file/shell/install_docker_disable_firewalld_centos7-aliyun.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +echo "-----------------------------------------禁用防火墙" +systemctl stop firewalld.service +systemctl disable firewalld.service + +echo "-----------------------------------------安装 docker 所需环境" + +yum install -y yum-utils device-mapper-persistent-data lvm2 + +echo "-----------------------------------------添加 repo(可能网络会很慢,有时候会报:Timeout,所以要多试几次)" +echo "-----------------------------------------官网的地址 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo" +echo "-----------------------------------------这里用阿里云进行加速,不然可能会出现无法安装,阿里云官网说明:https://help.aliyun.com/document_detail/60742.html" + +yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo +yum makecache fast + +echo "-----------------------------------------开始安装 docker" + +yum install -y docker-ce + +echo "-----------------------------------------启动 Docker" + +systemctl start docker.service + +echo "-----------------------------------------安装结束" + +echo "-----------------------------------------docker 加速" + +touch /etc/docker/daemon.json + +cat << EOF >> /etc/docker/daemon.json +{ + "registry-mirrors": ["https://ldhc17y9.mirror.aliyuncs.com"] +} +EOF + +systemctl daemon-reload +systemctl restart docker + +echo "-----------------------------------------运行 hello world 镜像" + +docker run hello-world + +echo "-----------------------------------------安装 docker compose" +echo "docker compose 的版本检查:https://docs.docker.com/compose/install/#install-compose" + +curl -L "https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + +chmod +x /usr/local/bin/docker-compose + +echo "-----------------------------------------输出 docker compose 版本号" + +docker-compose --version + + + + diff --git a/favorite-file/shell/install_docker_disable_firewalld_centos7.sh b/favorite-file/shell/install_docker_disable_firewalld_centos7.sh new file mode 100644 index 00000000..5b69cd09 --- /dev/null +++ b/favorite-file/shell/install_docker_disable_firewalld_centos7.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +echo "-----------------------------------------禁用防火墙" +systemctl stop firewalld.service +systemctl disable firewalld.service + + +echo "-----------------------------------------安装 docker 所需环境" + +yum install -y yum-utils device-mapper-persistent-data lvm2 + +echo "-----------------------------------------添加 repo(可能网络会很慢,有时候会报:Timeout,所以要多试几次)" + +yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo +yum makecache fast + +echo "-----------------------------------------开始安装 docker" + +yum install -y docker-ce + +echo "-----------------------------------------启动 Docker" + +systemctl start docker.service + +echo "-----------------------------------------安装结束" + +echo "-----------------------------------------运行 hello world 镜像" + +docker run hello-world + +echo "-----------------------------------------安装 docker compose" +echo "docker compose 的版本检查:https://docs.docker.com/compose/install/#install-compose" + +curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose + +chmod +x /usr/local/bin/docker-compose + +echo "-----------------------------------------输出 docker compose 版本号" + +docker-compose --version +systemctl restart docker.service +systemctl enable docker.service + + + diff --git a/favorite-file/shell/install_docker_k8s_disable_firewalld_centos7-aliyun.sh b/favorite-file/shell/install_docker_k8s_disable_firewalld_centos7-aliyun.sh new file mode 100644 index 00000000..66adafa2 --- /dev/null +++ b/favorite-file/shell/install_docker_k8s_disable_firewalld_centos7-aliyun.sh @@ -0,0 +1,49 @@ +#!/bin/sh + +echo "-----------------------------------------禁用防火墙" +systemctl stop firewalld.service +systemctl disable firewalld.service + +echo "-----------------------------------------安装 docker 所需环境" + +yum install -y yum-utils device-mapper-persistent-data lvm2 + +echo "-----------------------------------------添加 repo(可能网络会很慢,有时候会报:Timeout,所以要多试几次)" +echo "-----------------------------------------官网的地址 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo" +echo "-----------------------------------------这里用阿里云进行加速,不然可能会出现无法安装,阿里云官网说明:https://help.aliyun.com/document_detail/60742.html" + +yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo +yum makecache fast + +echo "-----------------------------------------开始安装 docker" + +yum install -y docker-ce-18.06.1.ce-3.el7 + +echo "-----------------------------------------启动 Docker" + +systemctl start docker.service +systemctl enable docker.service + +echo "-----------------------------------------安装结束" + +echo "-----------------------------------------docker 加速" + +touch /etc/docker/daemon.json + +cat << EOF >> /etc/docker/daemon.json +{ + "registry-mirrors": ["https://ldhc17y9.mirror.aliyuncs.com"] +} +EOF + +systemctl daemon-reload +systemctl restart docker + +echo "-----------------------------------------运行 hello world 镜像" + +docker run hello-world + + + + + diff --git a/favorite-file/shell/install_jdk_offline_to_bash.sh b/favorite-file/shell/install_jdk_offline_to_bash.sh new file mode 100644 index 00000000..1b60aeb0 --- /dev/null +++ b/favorite-file/shell/install_jdk_offline_to_bash.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +echo "判断常见的文件夹是否存在" + +if [ ! -d "/opt/setups" ]; then + mkdir /opt/setups +fi + +echo "判断 JDK 压缩包是否存在" + +if [ ! -f "/opt/setups/jdk-8u181-linux-x64.tar.gz" ]; then + echo "JDK 压缩包不存在" + exit 1 +fi + +echo "开始解压 JDK" +cd /opt/setups ; tar -zxf jdk-8u181-linux-x64.tar.gz + +if [ ! -d "/opt/setups/jdk1.8.0_181" ]; then + echo "JDK 解压失败,结束脚本" + exit 1 +fi + +echo "JDK 解压包移到 /usr/local/ 目录下" +mv jdk1.8.0_181/ /usr/local/ + +echo "JDK 写入系统变量到 profile" + +cat << EOF >> /etc/profile + +# JDK +JAVA_HOME=/usr/local/jdk1.8.0_181 +JRE_HOME=\$JAVA_HOME/jre +PATH=\$PATH:\$JAVA_HOME/bin +CLASSPATH=.:\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jar +export JAVA_HOME +export JRE_HOME +export PATH +export CLASSPATH + +EOF + + +echo "JDK 设置完成,需要你手动设置:source /etc/profile" \ No newline at end of file diff --git a/favorite-file/shell/install_jdk_offline_to_zsh.sh b/favorite-file/shell/install_jdk_offline_to_zsh.sh new file mode 100644 index 00000000..0c0c091b --- /dev/null +++ b/favorite-file/shell/install_jdk_offline_to_zsh.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +echo "判断常见的文件夹是否存在" + +if [ ! -d "/opt/setups" ]; then + mkdir /opt/setups +fi + +echo "判断 JDK 压缩包是否存在" + +if [ ! -f "/opt/setups/jdk-8u191-linux-x64.tar.gz" ]; then + echo "JDK 压缩包不存在" + exit 1 +fi + +echo "开始解压 JDK" +cd /opt/setups ; tar -zxf jdk-8u191-linux-x64.tar.gz + +if [ ! -d "/opt/setups/jdk1.8.0_191" ]; then + echo "JDK 解压失败,结束脚本" + exit 1 +fi + +echo "JDK 解压包移到 /usr/local/ 目录下" +mv jdk1.8.0_191/ /usr/local/ + +echo "JDK 写入系统变量到 zshrc" + +cat << EOF >> ~/.zshrc + +# JDK +JAVA_HOME=/usr/local/jdk1.8.0_191 +JRE_HOME=\$JAVA_HOME/jre +PATH=\$PATH:\$JAVA_HOME/bin +CLASSPATH=.:\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jar +export JAVA_HOME +export JRE_HOME +export PATH +export CLASSPATH + +EOF + + +echo "JDK 设置完成,需要你手动设置:source ~/.zshrc" \ No newline at end of file diff --git a/favorite-file/shell/auto_install_jdk.sh b/favorite-file/shell/install_jdk_online.sh similarity index 69% rename from favorite-file/shell/auto_install_jdk.sh rename to favorite-file/shell/install_jdk_online.sh index 7a6fa009..d55e05dd 100644 --- a/favorite-file/shell/auto_install_jdk.sh +++ b/favorite-file/shell/install_jdk_online.sh @@ -33,13 +33,17 @@ mv jdk1.8.0_151/ /usr/program/ echo "JDK 写入系统变量到 zshrc" -echo 'JAVA_HOME=/usr/program/jdk1.8.0_151' >> ~/.zshrc -echo 'JRE_HOME=$JAVA_HOME/jre' >> ~/.zshrc -echo 'PATH=$PATH:$JAVA_HOME/bin' >> ~/.zshrc -echo 'CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar' >> ~/.zshrc -echo 'export JAVA_HOME' >> ~/.zshrc -echo 'export JRE_HOME' >> ~/.zshrc -echo 'export PATH' >> ~/.zshrc -echo 'export CLASSPATH' >> ~/.zshrc +cat << EOF >> ~/.zshrc + +# JDK +JAVA_HOME=/usr/local/jdk1.8.0_151 +JRE_HOME=\$JAVA_HOME/jre +PATH=\$PATH:\$JAVA_HOME/bin +CLASSPATH=.:\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jar +export JAVA_HOME +export JRE_HOME +export PATH +export CLASSPATH +EOF echo "JDK 设置完成,需要你手动设置:source ~/.zshrc" \ No newline at end of file diff --git a/favorite-file/shell/install_maven_offline_to_bash.sh b/favorite-file/shell/install_maven_offline_to_bash.sh new file mode 100644 index 00000000..179cf3fa --- /dev/null +++ b/favorite-file/shell/install_maven_offline_to_bash.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +echo "判断常见的文件夹是否存在" + +if [ ! -d "/opt/setups" ]; then + mkdir /opt/setups +fi + +echo "判断 Maven 压缩包是否存在" + +if [ ! -f "/opt/setups/apache-maven-3.5.4-bin.tar.gz" ]; then + echo "Maven 压缩包不存在" + exit 1 +fi + +echo "开始解压 Maven" +cd /opt/setups ; tar -zxf apache-maven-3.5.4-bin.tar.gz + +if [ ! -d "/opt/setups/apache-maven-3.5.4" ]; then + echo "Maven 解压失败,结束脚本" + exit 1 +fi + +echo "Maven 解压包移到 /usr/local/ 目录下" +mv apache-maven-3.5.4/ /usr/local/ + +echo "Maven 写入系统变量到 profile" + +cat << EOF >> /etc/profile + +# Maven +M3_HOME=/usr/local/apache-maven-3.5.4 +MAVEN_HOME=/usr/local/apache-maven-3.5.4 +PATH=\$PATH:\$M3_HOME/bin +MAVEN_OPTS="-Xms256m -Xmx356m" +export M3_HOME +export MAVEN_HOME +export PATH +export MAVEN_OPTS + +EOF + + +echo "Maven 设置完成,需要你手动设置:source /etc/profile" \ No newline at end of file diff --git a/favorite-file/shell/install_maven_offline_to_zsh.sh b/favorite-file/shell/install_maven_offline_to_zsh.sh new file mode 100644 index 00000000..2454bb59 --- /dev/null +++ b/favorite-file/shell/install_maven_offline_to_zsh.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +echo "判断常见的文件夹是否存在" + +if [ ! -d "/opt/setups" ]; then + mkdir /opt/setups +fi + +echo "判断 Maven 压缩包是否存在" + +if [ ! -f "/opt/setups/apache-maven-3.5.4-bin.tar.gz" ]; then + echo "Maven 压缩包不存在" + exit 1 +fi + +echo "开始解压 Maven" +cd /opt/setups ; tar -zxf apache-maven-3.5.4-bin.tar.gz + +if [ ! -d "/opt/setups/apache-maven-3.5.4" ]; then + echo "Maven 解压失败,结束脚本" + exit 1 +fi + +echo "Maven 解压包移到 /usr/local/ 目录下" +mv apache-maven-3.5.4/ /usr/local/ + +echo "Maven 写入系统变量到 zshrc" + +cat << EOF >> ~/.zshrc + +# Maven +M3_HOME=/usr/local/apache-maven-3.5.4 +MAVEN_HOME=/usr/local/apache-maven-3.5.4 +PATH=\$PATH:\$M3_HOME/bin +MAVEN_OPTS="-Xms256m -Xmx356m" +export M3_HOME +export MAVEN_HOME +export PATH +export MAVEN_OPTS + +EOF + + +echo "Maven 设置完成,需要你手动设置:source ~/.zshrc" \ No newline at end of file diff --git a/favorite-file/shell/install_mycat_offline.sh b/favorite-file/shell/install_mycat_offline.sh new file mode 100644 index 00000000..eb0ee862 --- /dev/null +++ b/favorite-file/shell/install_mycat_offline.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +echo "判断常见的文件夹是否存在" + +if [ ! -d "/opt/setups" ]; then + mkdir /opt/setups +fi + +echo "判断是否有 JDK 环境" + +if [ -z $JAVA_HOME ];then + echo "没有 JAVA_HOME 环境变量" + exit 1 +fi + +echo "判断 /opt 目录下 mycat 压缩包是否存在" + +if [ ! -f "/opt/setups/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz" ]; then + echo "mycat 压缩包是否存在不存在" + exit 1 +fi + +echo "解压压缩包" + +cd /opt/setups ; tar -zxf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz + +echo "把解压后目录移到 /usr/local/ 目录下" +mv /opt/setups/mycat /usr/local/ + +echo "写入系统变量到 zshrc" + +echo 'MYCAT_HOME=/usr/local/mycat' >> ~/.zshrc +echo 'PATH=$PATH:$MYCAT_HOME/bin' >> ~/.zshrc +echo 'export MYCAT_HOME' >> ~/.zshrc +echo 'export PATH' >> ~/.zshrc +echo "mycat 设置完成,需要你手动设置:source ~/.zshrc" + + diff --git a/favorite-file/shell/install_mysql_centos6.sh b/favorite-file/shell/install_mysql5.6_offline_centos6.sh similarity index 100% rename from favorite-file/shell/install_mysql_centos6.sh rename to favorite-file/shell/install_mysql5.6_offline_centos6.sh diff --git a/favorite-file/shell/install_mysql5.6_offline_centos7.sh b/favorite-file/shell/install_mysql5.6_offline_centos7.sh new file mode 100644 index 00000000..e030a3dc --- /dev/null +++ b/favorite-file/shell/install_mysql5.6_offline_centos7.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +echo "安装 mysql 开始" + +echo "判断常见的文件夹是否存在" + +if [ ! -d "/opt/setups" ]; then + mkdir /opt/setups +fi + +echo "判断 JDK 压缩包是否存在" + +if [ ! -f "/opt/setups/mysql-5.6.35.tar.gz" ]; then + echo "mysql 压缩包不存在" + exit 1 +fi + +cd /opt/setups + +tar zxvf mysql-5.6.35.tar.gz + +mv /opt/setups/mysql-5.6.35 /usr/local/ + +yum install -y make gcc-c++ cmake bison-devel ncurses-devel autoconf + +cd /usr/local/mysql-5.6.35/ + +mkdir -p /usr/local/mysql/data + +cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data -DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS:STRING=utf8 -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DENABLED_LOCAL_INFILE=1 + +make + +make install + +cp /usr/local/mysql-5.6.35/support-files/mysql.server /etc/init.d/mysql + +chmod 755 /etc/init.d/mysql + +chkconfig mysql on + +cp /usr/local/mysql-5.6.35/support-files/my-default.cnf /etc/my.cnf + +rm -rf /usr/local/mysql-5.6.35/ + +groupadd mysql + +useradd -g mysql mysql -s /bin/false + +chown -R mysql:mysql /usr/local/mysql/data + +/usr/local/mysql/scripts/mysql_install_db --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --skip-name-resolve --user=mysql + +ln -s /usr/local/mysql/bin/mysql /usr/bin + +ln -s /usr/local/mysql/bin/mysqladmin /usr/bin + +ln -s /usr/local/mysql/bin/mysqldump /usr/bin + +ln -s /usr/local/mysql/bin/mysqlslap /usr/bin + +echo "防火墙放行 3306 端口" +systemctl restart firewalld.service +firewall-cmd --zone=public --add-port=3306/tcp --permanent +firewall-cmd --reload +systemctl stop firewalld.service + +echo "安装 mysql 结束,现在需要手动设置防火墙和禁用 selinux." \ No newline at end of file diff --git a/favorite-file/shell/install_mysql5.7_offline_centos7.sh b/favorite-file/shell/install_mysql5.7_offline_centos7.sh new file mode 100644 index 00000000..6ea0b3cb --- /dev/null +++ b/favorite-file/shell/install_mysql5.7_offline_centos7.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +echo "安装 mysql 开始" +echo "必须准备两个文件:mysql-5.7.21.tar.gz 和 boost_1_59_0.tar.gz" +echo "mysql 5.7 依赖 boost,官网说明:https://dev.mysql.com/doc/mysql-sourcebuild-excerpt/5.7/en/source-installation.html" +echo "boost 下载地址(79M):http://www.boost.org/users/history/version_1_59_0.html" + +if [ ! -f "/opt/setups/mysql-5.7.21.tar.gz" ]; then + echo "缺少 mysql-5.7.21.tar.gz 文件,结束脚本" + exit 1 +fi + +if [ ! -f "/opt/setups/boost_1_59_0.tar.gz" ]; then + echo "缺少 boost_1_59_0.tar.gz 文件,结束脚本" + exit 1 +fi + +cd /opt/setups + +tar zxvf mysql-5.7.21.tar.gz + +mv /opt/setups/mysql-5.7.21 /usr/local/ + +tar zxvf boost_1_59_0.tar.gz + +mv /opt/setups/boost_1_59_0 /usr/local/ + +yum install -y make gcc-c++ cmake bison-devel ncurses-devel + +cd /usr/local/mysql-5.7.21/ + +mkdir -p /usr/local/mysql/data + +cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data -DWITH_BOOST=/usr/local/boost_1_59_0 -DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS:STRING=utf8 -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DENABLED_LOCAL_INFILE=1 + +make + +make install + +cp /usr/local/mysql-5.7.21/support-files/mysql.server /etc/init.d/mysql + +chmod 755 /etc/init.d/mysql + +chkconfig mysql on + +echo "mysql 5.7 这个文件没了,需要自己创建一个" + +cp /usr/local/mysql-5.7.21/support-files/my-default.cnf /etc/my.cnf + +rm -rf /usr/local/mysql-5.7.21/ + +groupadd mysql + +useradd -g mysql mysql -s /bin/false + +chown -R mysql:mysql /usr/local/mysql/data + +/usr/local/mysql/scripts/mysql_install_db --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --skip-name-resolve --user=mysql + +ln -s /usr/local/mysql/bin/mysql /usr/bin + +ln -s /usr/local/mysql/bin/mysqladmin /usr/bin + +ln -s /usr/local/mysql/bin/mysqldump /usr/bin + +ln -s /usr/local/mysql/bin/mysqlslap /usr/bin + +echo "防火墙放行 3306 端口" +systemctl restart firewalld.service +firewall-cmd --zone=public --add-port=3306/tcp --permanent +firewall-cmd --reload +systemctl stop firewalld.service + +echo "安装 mysql 结束,现在需要手动设置防火墙和禁用 selinux." \ No newline at end of file diff --git a/favorite-file/shell/install_mysql_centos7.sh b/favorite-file/shell/install_mysql_centos7.sh deleted file mode 100644 index 11d42b92..00000000 --- a/favorite-file/shell/install_mysql_centos7.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/sh - -echo "安装 mysql 开始" - -cd /opt/setups - -tar zxvf mysql-5.6.35.tar.gz - -mv /opt/setups/mysql-5.6.35 /usr/program/ - -yum install -y make gcc-c++ cmake bison-devel ncurses-devel - -cd /usr/program/mysql-5.6.35/ - -mkdir -p /usr/program/mysql/data - -cmake -DCMAKE_INSTALL_PREFIX=/usr/program/mysql -DMYSQL_DATADIR=/usr/program/mysql/data -DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS:STRING=utf8 -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DENABLED_LOCAL_INFILE=1 - -make - -make install - -cp /usr/program/mysql-5.6.35/support-files/mysql.server /etc/init.d/mysql - -chmod 755 /etc/init.d/mysql - -chkconfig mysql on - -cp /usr/program/mysql-5.6.35/support-files/my-default.cnf /etc/my.cnf - -rm -rf /usr/program/mysql-5.6.35/ - -groupadd mysql - -useradd -g mysql mysql -s /bin/false - -chown -R mysql:mysql /usr/program/mysql/data - -/usr/program/mysql/scripts/mysql_install_db --basedir=/usr/program/mysql --datadir=/usr/program/mysql/data --skip-name-resolve --user=mysql - -ln -s /usr/program/mysql/bin/mysql /usr/bin - -ln -s /usr/program/mysql/bin/mysqladmin /usr/bin - -ln -s /usr/program/mysql/bin/mysqldump /usr/bin - -ln -s /usr/program/mysql/bin/mysqlslap /usr/bin - -echo "防火墙放行 3306 端口" -systemctl restart firewalld.service -firewall-cmd --zone=public --add-port=3306/tcp --permanent -firewall-cmd --reload -systemctl stop firewalld.service - -echo "安装 mysql 结束,现在需要手动设置防火墙和禁用 selinux." \ No newline at end of file diff --git a/favorite-file/shell/install_nginx_centos7.sh b/favorite-file/shell/install_nginx_centos7.sh index 207e3e29..f2bd28eb 100644 --- a/favorite-file/shell/install_nginx_centos7.sh +++ b/favorite-file/shell/install_nginx_centos7.sh @@ -8,10 +8,6 @@ if [ ! -d "/opt/setups" ]; then mkdir /opt/setups fi -if [ ! -d "/usr/program" ]; then - mkdir /usr/program -fi - if [ ! -d "/usr/local/nginx" ]; then mkdir -p /usr/local/nginx fi @@ -31,17 +27,17 @@ fi echo "下载 Nginx" cd /opt/setups -wget https://nginx.org/download/nginx-1.12.2.tar.gz +wget https://nginx.org/download/nginx-1.14.0.tar.gz -if [ ! -f "/opt/setups/nginx-1.12.2.tar.gz" ]; then +if [ ! -f "/opt/setups/nginx-1.14.0.tar.gz" ]; then echo "Nginx 下载失败,结束脚本" exit 1 fi echo "Nginx 下载成功,开始解压 Nginx" -tar -zxf nginx-1.12.2.tar.gz +tar -zxf nginx-1.14.0.tar.gz -if [ ! -d "/opt/setups/nginx-1.12.2" ]; then +if [ ! -d "/opt/setups/nginx-1.14.0" ]; then echo "Nginx 解压失败,结束脚本" exit 1 fi @@ -50,15 +46,17 @@ echo "安装源码安装依赖" yum install -y gcc gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel echo "开始安装 Nginx" -cd nginx-1.12.2/ +cd nginx-1.14.0/ ./configure --prefix=/usr/local/nginx --pid-path=/var/local/nginx/nginx.pid --lock-path=/var/lock/nginx/nginx.lock --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --with-http_gzip_static_module --http-client-body-temp-path=/var/temp/nginx/client --http-proxy-temp-path=/var/temp/nginx/proxy --http-fastcgi-temp-path=/var/temp/nginx/fastcgi --http-uwsgi-temp-path=/var/temp/nginx/uwsgi --with-http_ssl_module --http-scgi-temp-path=/var/temp/nginx/scgi make make install echo "防火墙放行 80 端口" +systemctl restart firewalld.service firewall-cmd --zone=public --add-port=80/tcp --permanent firewall-cmd --reload +systemctl restart firewalld.service echo "启动 Nginx" /usr/local/nginx/sbin/nginx diff --git a/favorite-file/shell/install_redis_centos7.sh b/favorite-file/shell/install_redis_centos7.sh index c87bb527..ec7246dd 100644 --- a/favorite-file/shell/install_redis_centos7.sh +++ b/favorite-file/shell/install_redis_centos7.sh @@ -7,10 +7,6 @@ if [ ! -d "/opt/setups" ]; then mkdir /opt/setups fi -if [ ! -d "/usr/program" ]; then - mkdir /usr/program -fi - echo "下载 redis" cd /opt/setups @@ -37,15 +33,15 @@ if [ ! -d "/opt/setups/redis-4.0.6" ]; then exit 1 fi -mv redis-4.0.6/ /usr/program/ +mv redis-4.0.6/ /usr/local/ -cd /usr/program/redis-4.0.6 +cd /usr/local/redis-4.0.6 make make install -cp /usr/program/redis-4.0.6/redis.conf /etc/ +cp /usr/local/redis-4.0.6/redis.conf /etc/ sed -i 's/daemonize no/daemonize yes/g' /etc/redis.conf @@ -55,6 +51,6 @@ echo "防火墙放行 6379 端口" firewall-cmd --zone=public --add-port=6379/tcp --permanent firewall-cmd --reload -rm -rf /usr/program/redis-4.0.6 +rm -rf /usr/local/redis-4.0.6 echo "安装结束" diff --git a/favorite-file/shell/auto_install_tomcat_centos6.sh b/favorite-file/shell/install_tomcat_centos6.sh similarity index 100% rename from favorite-file/shell/auto_install_tomcat_centos6.sh rename to favorite-file/shell/install_tomcat_centos6.sh diff --git a/favorite-file/shell/auto_install_tomcat_centos7.sh b/favorite-file/shell/install_tomcat_centos7.sh similarity index 69% rename from favorite-file/shell/auto_install_tomcat_centos7.sh rename to favorite-file/shell/install_tomcat_centos7.sh index fa7b50b8..c85aad61 100644 --- a/favorite-file/shell/auto_install_tomcat_centos7.sh +++ b/favorite-file/shell/install_tomcat_centos7.sh @@ -6,10 +6,6 @@ if [ ! -d "/opt/setups" ]; then mkdir /opt/setups fi -if [ ! -d "/usr/program" ]; then - mkdir /usr/program -fi - echo "下载 Tomcat" cd /opt/setups @@ -28,13 +24,13 @@ if [ ! -d "/opt/setups/apache-tomcat-8.0.46" ]; then exit 1 fi -echo "Tomcat 解压包移到 /usr/program/ 目录下" -mv apache-tomcat-8.0.46/ /usr/program/ -mv /usr/program/apache-tomcat-8.0.46/ /usr/program/tomcat8/ +echo "Tomcat 解压包移到 /usr/local/ 目录下" +mv apache-tomcat-8.0.46/ /usr/local/ +mv /usr/local/apache-tomcat-8.0.46/ /usr/local/tomcat8/ echo "防火墙放行 8080 端口" firewall-cmd --zone=public --add-port=8080/tcp --permanent firewall-cmd --reload echo "运行 Tomcat" -sh /usr/program/tomcat8/bin/startup.sh ; tail -200f /usr/program/tomcat8/logs/catalina.out \ No newline at end of file +sh /usr/local/tomcat8/bin/startup.sh ; tail -200f /usr/local/tomcat8/logs/catalina.out \ No newline at end of file diff --git a/favorite-file/shell/install_tomcat_offline_centos7.sh b/favorite-file/shell/install_tomcat_offline_centos7.sh new file mode 100644 index 00000000..563756b6 --- /dev/null +++ b/favorite-file/shell/install_tomcat_offline_centos7.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +echo "判断常见的文件夹是否存在" + +if [ ! -d "/opt/setups" ]; then + mkdir /opt/setups +fi + + +echo "判断 tomcat 压缩包是否存在" + +if [ ! -f "/opt/setups/apache-tomcat-8.0.46.tar.gz" ]; then + echo "JDK 压缩包不存在" + exit 1 +fi + + +cd /opt/setups + +echo "开始解压 Tomcat" + +tar -zxf apache-tomcat-8.0.46.tar.gz + +if [ ! -d "/opt/setups/apache-tomcat-8.0.46" ]; then + echo "Tomcat 解压失败,结束脚本" + exit 1 +fi + +echo "Tomcat 解压包移到 /usr/local/ 目录下" +mv apache-tomcat-8.0.46/ /usr/local/ +mv /usr/local/apache-tomcat-8.0.46/ /usr/local/tomcat8/ + +echo "防火墙放行 8080 端口" +firewall-cmd --zone=public --add-port=8080/tcp --permanent +firewall-cmd --reload + +echo "运行 Tomcat" +sh /usr/local/tomcat8/bin/startup.sh ; tail -200f /usr/local/tomcat8/logs/catalina.out \ No newline at end of file diff --git a/favorite-file/shell/mysql_backup.sh b/favorite-file/shell/mysql_backup.sh new file mode 100644 index 00000000..541c77cb --- /dev/null +++ b/favorite-file/shell/mysql_backup.sh @@ -0,0 +1,17 @@ +#!/bin/bash + + +backupDatetime=$1 + +if [ "$backupDatetime" = "" ]; +then + echo -e "\033[0;31m 请输入备份日期 \033[0m" + exit 1 +fi + +echo "备份日期 = $backupDatetime" + +/usr/bin/mysqldump -u root --password=123456 数据库名 > /opt/mydb-"$backupDatetime".sql + + + diff --git a/favorite-file/shell/shell-for.sh b/favorite-file/shell/shell-for.sh new file mode 100644 index 00000000..9b92b372 --- /dev/null +++ b/favorite-file/shell/shell-for.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# 循环总次数 +totalDegree=$1 + +# 如果没有传参,则默认值是 10 +if [ "$totalDegree" = "" ]; +then + totalDegree=10 +fi + +for((timeTemp = 0; timeTemp <= $totalDegree; timeTemp = timeTemp + 5)) +do + echo "timeTemp=$timeTemp" +done + + + diff --git a/favorite-file/shell/shell-with-param-demo.sh b/favorite-file/shell/shell-with-param-demo.sh new file mode 100644 index 00000000..f59e9a79 --- /dev/null +++ b/favorite-file/shell/shell-with-param-demo.sh @@ -0,0 +1,89 @@ +#!/bin/bash + + +methodParam=$1 +SpringBoot=$2 +SpringBootPath=$3 + +if [ "$methodParam" = "" ]; +then + echo -e "\033[0;31m 未输入操作名 \033[0m \033[0;34m {start|stop|restart|status} \033[0m" + exit 1 +fi + +if [ "$SpringBoot" = "" ]; +then + echo -e "\033[0;31m 未输入应用名 \033[0m" + exit 1 +fi + +if [ "$SpringBootPath" = "" ]; +then + echo -e "\033[0;31m 未输入应用路径 \033[0m" + exit 1 +fi + +echo "操作名 = $methodParam" +echo "应用名 = $2" +echo "应用路径 = $3" + +function start() +{ + count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l` + if [ $count != 0 ];then + echo "$SpringBoot is running..." + else + echo "Start $SpringBoot success..." + cd $SpringBootPath + BUILD_ID=dontKillMe nohup java -jar $SpringBoot > /opt/run-log.log 2>&1 & + fi +} + +function stop() +{ + echo "Stop $SpringBoot" + boot_id=`ps -ef |grep java|grep $SpringBoot|grep -v grep|awk '{print $2}'` + count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l` + + if [ $count != 0 ];then + kill $boot_id + count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l` + + boot_id=`ps -ef |grep java|grep $SpringBoot|grep -v grep|awk '{print $2}'` + kill -9 $boot_id + fi +} + +function restart() +{ + stop + sleep 2 + start +} + +function status() +{ + count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l` + if [ $count != 0 ];then + echo "$SpringBoot is running..." + else + echo "$SpringBoot is not running..." + fi +} + +case $methodParam in + start) + start;; + stop) + stop;; + restart) + restart;; + status) + status;; + *) + + echo -e "\033[0;31m Usage: \033[0m \033[0;34m sh $0 {start|stop|restart|status} {SpringBootJarName} \033[0m\033[0;31m Example: \033[0m\033[0;33m sh $0 start esmart-test.jar \033[0m" +esac + + + diff --git a/images/CentOS-7-Install-a-0.jpg b/images/CentOS-7-Install-a-0.jpg new file mode 100644 index 00000000..acc0a75b Binary files /dev/null and b/images/CentOS-7-Install-a-0.jpg differ diff --git a/images/Zookeeper-Client-ZooInspector.png b/images/Zookeeper-Client-ZooInspector.png new file mode 100644 index 00000000..7a6eff76 Binary files /dev/null and b/images/Zookeeper-Client-ZooInspector.png differ diff --git a/images/Zookeeper-Client-zooweb.png b/images/Zookeeper-Client-zooweb.png new file mode 100644 index 00000000..41bb2c19 Binary files /dev/null and b/images/Zookeeper-Client-zooweb.png differ diff --git a/Alfresco-Install-And-Usage.md b/markdown-file/Alfresco-Install-And-Usage.md similarity index 87% rename from Alfresco-Install-And-Usage.md rename to markdown-file/Alfresco-Install-And-Usage.md index 04689f4a..dec91c07 100644 --- a/Alfresco-Install-And-Usage.md +++ b/markdown-file/Alfresco-Install-And-Usage.md @@ -24,8 +24,8 @@ - 然后会出现如下图这种步骤引导安装界面,带有简体中文版,选择 `简单` 的基本流程安装方式,默认都是下一步下一步。其实选择 `高级` 也基本上是下一步下一步的,只是可以看到更多细节。 - 在设置管理员密码上,我是:123456(默认用户名是:admin) -![alfresco 安装](images/Alfresco-Install-And-Settings-a-1.jpg) -![alfresco 安装](images/Alfresco-Install-And-Settings-a-2.jpg) +![alfresco 安装](../images/Alfresco-Install-And-Settings-a-1.jpg) +![alfresco 安装](../images/Alfresco-Install-And-Settings-a-2.jpg) - 安装完成后,可以选择开始启动程序。建议不勾选,我们来使用下面命令。 - 程序默认是安装在:**/opt/alfresco-community** @@ -35,8 +35,8 @@ - 停止程序:`./alfresco.sh stop` - 启动完成后,用浏览器打开:(如果你 Linux 防火墙关闭了,也可以直接用其他机子直接访问,把这台机子当做服务器用),可以看到如下内容: -![alfresco 安装](images/Alfresco-Install-And-Settings-a-3.jpg) -![alfresco 安装](images/Alfresco-Install-And-Settings-a-4.jpg) +![alfresco 安装](../images/Alfresco-Install-And-Settings-a-3.jpg) +![alfresco 安装](../images/Alfresco-Install-And-Settings-a-4.jpg) diff --git a/markdown-file/Ansible-Install-And-Settings.md b/markdown-file/Ansible-Install-And-Settings.md new file mode 100644 index 00000000..aed43c64 --- /dev/null +++ b/markdown-file/Ansible-Install-And-Settings.md @@ -0,0 +1,364 @@ +# Ansible 安装和配置 + + +## Ansible 说明 + +- Ansible 官网: +- Ansible 官网 Github: +- Ansible 官网文档: +- 简单讲:它的作用就是把写 shell 这件事变成标准化、模块化。方便更好的自动化运维 + +## 安装 + +- 官网说明: +- CentOS:`sudo yum install -y ansible` + - 查看版本:`ansible --version` + +------------------------------------------------------------------- + +## 配置基本概念 + +#### Ansible 基本配置文件顺序 + +- Ansible 执行的时候会按照以下顺序查找配置项,所以修改的时候要特别注意改的是哪个文件 + +``` +ANSIBLE_CONFIG (环境变量) +ansible.cfg (脚本所在当前目录下) +~/.ansible.cfg (用户家目录下,默认没有) +/etc/ansible/ansible.cfg(安装后会自动生成) +``` + + +#### 配置远程主机地址 (Ansible 称这些地址为 Inventory) + +- 假设我有 3 台机子: + - 192.168.0.223 + - 192.168.0.70 + - 192.168.0.103 +- 官网对此的配置说明: + +###### 给这三台机子设置免密登录的情况(一般推荐方式) + +- 编辑 Ansible 配置文件:`vim /etc/ansible/hosts` +- 添加如下内容 + +``` +[hadoop-host] +192.168.0.223 +192.168.0.70 +192.168.0.103 +``` + +- 其中 `[hadoop-host]` 表示这些主机代表的一个组名 + + +###### 如果不设置免密,直接采用账号密码(容易泄露信息) + + +- 编辑 Ansible 配置文件:`vim /etc/ansible/hosts` +- 添加如下内容 + +``` +[hadoop-host] +hadoop-master ansible_host=192.168.0.223 ansible_user=root ansible_ssh_pass=123456 +hadoop-node1 ansible_host=192.168.0.70 ansible_user=root ansible_ssh_pass=123456 +hadoop-node2 ansible_host=192.168.0.103 ansible_user=root ansible_ssh_pass=123456 +``` + + + +## 简单使用(`ad hoc`方式) + +- ad hoc 官网: + +##### 运行 Ansible + +- 运行 Ansible 的 `ping` 命令,看看配置正确时输出如下: + +``` +sudo ansible --private-key ~/.ssh/id_rsa all -m ping +``` + +- 让远程所有主机都执行 `ps` 命令,输出如下 + +``` +ansible all -a 'ps' +``` + +- 让远程所有 hadoop-host 组的主机都执行 `ps` 命令,输出如下 + +``` +ansible hadoop-host -a 'ps' +``` + +------------------------------------------------------------------- + +## Playbook 脚本方式 + +- 官网: +- 一些语法: +- playbook(剧本),顾名思义,就是需要定义一个脚本或者说配置文件,然后定义好要做什么。之后 ansible 就会根据 playbook 脚本对远程主机进行操作 + +#### 简单脚本 + +- 下面脚本让所有远程主机执行 `whoami` 命令,并把结果(当前用户名)输出到 `/opt/whoami.txt` 文件 +- 创建脚本文件:`vim /opt/simple-playbook.yml` + +``` +- hosts: all + tasks: + - name: whoami + shell: 'whoami > /opt/whoami.txt' +``` + +- 执行命令:`ansible-playbook /opt/simple-playbook.yml`,结果如下,并且 opt 下也有文件生成 + +``` +PLAY [all] ************************************************************************************************************************** + +TASK [Gathering Facts] ************************************************************************************************************** +ok: [192.168.0.223] +ok: [192.168.0.103] +ok: [192.168.0.70] + +TASK [whoami] *********************************************************************************************************************** +changed: [192.168.0.103] +changed: [192.168.0.223] +changed: [192.168.0.70] + +PLAY RECAP ************************************************************************************************************************** +192.168.0.103 : ok=2 changed=1 unreachable=0 failed=0 +192.168.0.223 : ok=2 changed=1 unreachable=0 failed=0 +192.168.0.70 : ok=2 changed=1 unreachable=0 failed=0 +``` + +------------------------------------------------------------------- + +## 平时用来测试 + +- 创建脚本文件:`vim /opt/test-playbook.yml` + +``` +- hosts: hadoop-test + remote_user: root + vars: + java_install_folder: /usr/local + tasks: + # 按行的方式写入 + - name: Set JAVA_HOME 1 + lineinfile: + dest=/etc/profile + line="JAVA_HOME={{ java_install_folder }}/jdk1.8.0_181" + # 按块的方式写入,#{mark} 会被自动替换成:begin 和 end 字符来包裹整块内容(我这里自己定义了词语) + - name: Set JAVA_HOME 2 + blockinfile: + path: /etc/profile + marker: "#{mark} JDK ENV" + marker_begin: "开始" + marker_end: "结束" + block: | + export JAVA_HOME={{ java_install_folder }}/jdk1.8.0_181 + export PATH=$PATH:$JAVA_HOME/bin +``` + +- 执行命令:`ansible-playbook /opt/test-playbook.yml` + +------------------------------------------------------------------- + +## 更多 playbook 实战 + + +#### 禁用防火墙(CentOS 7.x) + + +- 创建脚本文件:`vim /opt/disable-firewalld-playbook.yml` + +``` +- hosts: all + remote_user: root + tasks: + - name: Disable SELinux at next reboot + selinux: + state: disabled + - name: disable firewalld + command: "{{ item }}" + with_items: + - systemctl stop firewalld + - systemctl disable firewalld + - setenforce 0 +``` + + + +#### 基础环境(CentOS 7.x) + + +- 创建脚本文件:`vim /opt/install-basic-playbook.yml` + +``` +- hosts: all + remote_user: root + tasks: + - name: Disable SELinux at next reboot + selinux: + state: disabled + + - name: disable firewalld + command: "{{ item }}" + with_items: + - systemctl stop firewalld + - systemctl disable firewalld + - setenforce 0 + + - name: install-basic + command: "{{ item }}" + with_items: + - yum install -y zip unzip lrzsz git epel-release wget htop deltarpm + + - name: install-vim + shell: "{{ item }}" + with_items: + - yum install -y vim + - curl https://raw.githubusercontent.com/wklken/vim-for-server/master/vimrc > ~/.vimrc + + - name: install-docker + shell: "{{ item }}" + with_items: + - yum install -y yum-utils device-mapper-persistent-data lvm2 + - yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo + - yum makecache fast + - yum install -y docker-ce + - systemctl start docker.service + - docker run hello-world + + - name: install-docker-compose + shell: "{{ item }}" + with_items: + - curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose + - chmod +x /usr/local/bin/docker-compose + - docker-compose --version + - systemctl restart docker.service + - systemctl enable docker.service + +``` + + +- 执行命令:`ansible-playbook /opt/install-basic-playbook.yml` + +#### 修改 hosts + + +- 创建脚本文件:`vim /opt/hosts-playbook.yml` + +``` +- hosts: all + remote_user: root + tasks: + - name: update hosts + blockinfile: + path: /etc/hosts + block: | + 192.168.0.223 linux01 + 192.168.0.223 linux02 + 192.168.0.223 linux03 + 192.168.0.223 linux04 + 192.168.0.223 linux05 +``` + + +- 执行命令:`ansible-playbook /opt/hosts-playbook.yml` + + + +#### 部署 JDK + +- 创建脚本文件:`vim /opt/jdk8-playbook.yml` + +``` +- hosts: hadoop-host + remote_user: root + vars: + java_install_folder: /usr/local + tasks: + - name: copy jdk + copy: src=/opt/jdk-8u181-linux-x64.tar.gz dest={{ java_install_folder }} + + - name: tar jdk + shell: chdir={{ java_install_folder }} tar zxf jdk-8u181-linux-x64.tar.gz + + - name: set JAVA_HOME + blockinfile: + path: /etc/profile + marker: "#{mark} JDK ENV" + block: | + JAVA_HOME={{ java_install_folder }}/jdk1.8.0_181 + JRE_HOME=$JAVA_HOME/jre + PATH=$PATH:$JAVA_HOME/bin + CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar + export JAVA_HOME + export JRE_HOME + export PATH + export CLASSPATH + + - name: source profile + shell: source /etc/profile +``` + + +- 执行命令:`ansible-playbook /opt/jdk8-playbook.yml` + + + +#### 部署 Hadoop 集群 + +- 创建脚本文件:`vim /opt/hadoop-playbook.yml` +- 刚学 Ansible,不好动配置文件,所以就只保留环境部分的设置,其他部分自行手工~ + +``` +- hosts: hadoop-host + remote_user: root + tasks: + - name: Creates directory + file: + path: /data/hadoop/hdfs/name + state: directory + - name: Creates directory + file: + path: /data/hadoop/hdfs/data + state: directory + - name: Creates directory + file: + path: /data/hadoop/hdfs/tmp + state: directory + + - name: set HADOOP_HOME + blockinfile: + path: /etc/profile + marker: "#{mark} HADOOP ENV" + block: | + HADOOP_HOME=/usr/local/hadoop + PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin + export HADOOP_HOME + export PATH + + - name: source profile + shell: source /etc/profile +``` + + +- 执行命令:`ansible-playbook /opt/hadoop-playbook.yml` + + + + + +------------------------------------------------------------------- + + +## 资料 + +- [ANSIBLE模块 - shell和command区别](https://www.jianshu.com/p/081139f73613) +- +- +- \ No newline at end of file diff --git a/Bash-Other-Bash.md b/markdown-file/Bash-Other-Bash.md similarity index 93% rename from Bash-Other-Bash.md rename to markdown-file/Bash-Other-Bash.md index 5f8782c5..2ce9fcd8 100644 --- a/Bash-Other-Bash.md +++ b/markdown-file/Bash-Other-Bash.md @@ -10,6 +10,7 @@ - `rpm -ivh example.rpm`,安装 example.rpm 包并在安装过程中显示正在安装的文件信息及安装进度 - 查询 - `rpm -qa | grep jdk`,查看 jdk 是否被安装 + - `rpm -ql jdk`,查看 jdk 是否被安装 - 卸载 - `rpm -e jdk`,卸载 jdk(一般卸载的时候都要先用 rpm -qa 看下整个软件的全名) - YUM 软件管理: @@ -26,4 +27,5 @@ ## 资料 +- diff --git a/Bash.md b/markdown-file/Bash.md similarity index 76% rename from Bash.md rename to markdown-file/Bash.md index 04f35103..593b8ff6 100644 --- a/Bash.md +++ b/markdown-file/Bash.md @@ -15,7 +15,9 @@ - `pwd`,显示当前目录路径(常用) - `firefox&`,最后后面的 **&** 符号,表示使用后台方式打开 Firefox,然后显示该进程的 PID 值 - `jobs`,查看后台运行的程序列表 -- `ifconfig`,查看 IP 等信息(常用) +- `ifconfig`,查看内网 IP 等信息(常用) +- `curl ifconfig.me`,查看外网 IP 信息 +- `curl ip.cn`,查看外网 IP 信息 - `locate 搜索关键字`,快速搜索系统文件/文件夹(类似 Windows 上的 everything 索引式搜索)(常用) - `updatedb`,配合上面的 locate,给 locate 的索引更新(locate 默认是一天更新一次索引)(常用) - `date`,查看系统时间(常用) @@ -23,7 +25,6 @@ - `date -s18:24`,设置时间,如果要同时更改 BIOS 时间,再执行 `hwclock --systohc`(常用) - `cal`,在终端中查看日历,肯定没有农历显示的 - `uptime`,查看系统已经运行了多久,当前有几个用户等信息(常用) -- `echo "字符串内容"`,输出 "字符串内容" - `cat 文件路名`,显示文件内容(属于打印语句) - `cat -n 文件名`,显示文件,并每一行内容都编号 - `more 文件名`,用分页的方式查看文件内容(按 space 翻下一页,按 *Ctrl + B* 返回上页) @@ -31,7 +32,6 @@ - 按 **j** 向下移动,按 **k** 向上移动 - 按 **/** 后,输入要查找的字符串内容,可以对文件进行向下查询,如果存在多个结果可以按 **n** 调到下一个结果出 - 按 **?** 后,输入要查找的字符串内容,可以对文件进行向上查询,如果存在多个结果可以按 **n** 调到下一个结果出 -- `tail -200f 文件名`,查看文件被更新的新内容尾 200 行,如果文件还有在新增可以动态查看到(一般用于查看日记文件) - `shutdown` - `shutdown -hnow`,立即关机 - `shutdown -h+10`,10 分钟后关机 @@ -48,28 +48,30 @@ - `last`,显示最近登录的帐户及时间 - `lastlog`,显示系统所有用户各自在最近登录的记录,如果没有登录过的用户会显示 **从未登陆过** - `ls`,列出当前目录下的所有没有隐藏的文件 / 文件夹。 - - `ls -a`,列出包括以.号开头的隐藏文件 / 文件夹(也就是所有文件) + - `ls -a`,列出包括以.号开头的隐藏文件 / 文件夹(也就是所有文件) - `ls -R`,显示出目录下以及其所有子目录的文件 / 文件夹(递归地方式,不显示隐藏的文件) - `ls -a -R`,显示出目录下以及其所有子目录的文件 / 文件夹(递归地方式,显示隐藏的文件) - - `ls -l`,列出目录下所有文件的权限、所有者、文件大小、修改时间及名称(也就是显示详细信息,不显示隐藏文件)。显示出来的效果如下: - - ``` nginx - -rwxr-xr-x. 1 root root 4096 3月 26 10:57,其中最前面的 - 表示这是一个普通文件 - lrwxrwxrwx. 1 root root 4096 3月 26 10:57,其中最前面的 l 表示这是一个链接文件,类似 Windows 的快捷方式 - drwxr-xr-x. 5 root root 4096 3月 26 10:57,其中最前面的 d 表示这是一个目录 - ``` - + - `ls -al`,列出目录下所有文件(包含隐藏)的权限、所有者、文件大小、修改时间及名称(也就是显示详细信息) - `ls -ld 目录名`,显示该目录的基本信息 - `ls -t`,依照文件最后修改时间的顺序列出文件名。 - `ls -F`,列出当前目录下的文件名及其类型。以 **/** 结尾表示为目录名,以 **\*** 结尾表示为可执行文件,以 **@** 结尾表示为符号连接 - `ls -lg`,同上,并显示出文件的所有者工作组名。 - `ls -lh`,查看文件夹类文件详细信息,文件大小,文件修改时间 - `ls /opt | head -5`,显示 opt 目录下前 5 条记录 + - `ls -l | grep '.jar'`,查找当前目录下所有 jar 文件 - `ls -l /opt |grep "^-"|wc -l`,统计 opt 目录下文件的个数,不会递归统计 - `ls -lR /opt |grep "^-"|wc -l`,统计 opt 目录下文件的个数,会递归统计 - `ls -l /opt |grep "^d"|wc -l`,统计 opt 目录下目录的个数,不会递归统计 - `ls -lR /opt |grep "^d"|wc -l`,统计 opt 目录下目录的个数,会递归统计 - `ls -lR /opt |grep "js"|wc -l`,统计 opt 目录下 js 文件的个数,会递归统计 + - `ls -l`,列出目录下所有文件的权限、所有者、文件大小、修改时间及名称(也就是显示详细信息,不显示隐藏文件)。显示出来的效果如下: + +``` nginx +-rwxr-xr-x. 1 root root 4096 3月 26 10:57,其中最前面的 - 表示这是一个普通文件 +lrwxrwxrwx. 1 root root 4096 3月 26 10:57,其中最前面的 l 表示这是一个链接文件,类似 Windows 的快捷方式 +drwxr-xr-x. 5 root root 4096 3月 26 10:57,其中最前面的 d 表示这是一个目录 +``` + - `cd`,目录切换 - `cd ..`,改变目录位置至当前目录的父目录(上级目录)。 - `cd ~`,改变目录位置至用户登录时的工作目录。 @@ -105,18 +107,42 @@ - `find . -name "lin*" -exec ls -l {} \;`,当前目录搜索lin开头的文件,然后用其搜索后的结果集,再执行ls -l的命令(这个命令可变,其他命令也可以),其中 -exec 和 {} \; 都是固定格式 - `find /opt -type f -size +800M -print0 | xargs -0 du -h | sort -nr`,找出 /opt 目录下大于 800 M 的文件 - `find / -name "*tower*" -exec rm {} \;`,找到文件并删除 + - `find / -name "*tower*" -exec mv {} /opt \;`,找到文件并移到 opt 目录 + - `find . -name "*" |xargs grep "youmeek"`,递归查找当前文件夹下所有文件内容中包含 youmeek 的文件 + - `find . -size 0 | xargs rm -f &`,删除当前目录下文件大小为0的文件 - `du -hm --max-depth=2 | sort -nr | head -12`,找出系统中占用容量最大的前 12 个目录 - `cat /etc/resolv.conf`,查看 DNS 设置 - `netstat -tlunp`,查看当前运行的服务,同时可以查看到:运行的程序已使用端口情况 - `env`,查看所有系统变量 - `export`,查看所有系统变量 -- `echo $JAVA_HOME`,查看指定系统变量的值,这里查看的是自己配置的 JAVA_HOME。 +- `echo` + - `echo $JAVA_HOME`,查看指定系统变量的值,这里查看的是自己配置的 JAVA_HOME。 + - `echo "字符串内容"`,输出 "字符串内容" + - `echo > aa.txt`,清空 aa.txt 文件内容(类似的还有:`: > aa.txt`,其中 : 是一个占位符, 不产生任何输出) - `unset $JAVA_HOME`,删除指定的环境变量 - `ln -s /opt/data /opt/logs/data`,表示给 /opt/logs 目录下创建一个名为 data 的软链接,该软链接指向到 /opt/data - +- `grep` + - `shell grep -H '安装' *.sh`,查找当前目录下所有 sh 类型文件中,文件内容包含 `安装` 的当前行内容 + - `grep 'test' java*`,显示当前目录下所有以 java 开头的文件中包含 test 的行 + - `grep 'test' spring.ini docker.sh`,显示当前目录下 spring.ini docker.sh 两个文件中匹配 test 的行 +- `ps` + - `ps –ef|grep java`,查看当前系统中有关 java 的所有进程 + - `ps -ef|grep --color java`,高亮显示当前系统中有关 java 的所有进程 +- `kill` + - `kill 1234`,结束 pid 为 1234 的进程 + - `kill -9 1234`,强制结束 pid 为 1234 的进程(慎重) + - `killall java`,结束同一进程组内的所有为 java 进程 + - `ps -ef|grep hadoop|grep -v grep|cut -c 9-15|xargs kill -9`,结束包含关键字 hadoop 的所有进程 +- `head` + - `head -n 10 spring.ini`,查看当前文件的前 10 行内容 +- `tail` + - `tail -n 10 spring.ini`,查看当前文件的后 10 行内容 + - `tail -200f 文件名`,查看文件被更新的新内容尾 200 行,如果文件还有在新增可以动态查看到(一般用于查看日记文件) ## 用户、权限-相关命令 +- 使用 pem 证书登录:`ssh -i /opt/mykey.pem root@192.168.0.70` + - 证书权限不能太大,不然无法使用:`chmod 600 mykey.pem` - `hostname`,查看当前登陆用户全名 - `cat /etc/group`,查看所有组 - `cat /etc/passwd`,查看所有用户 @@ -144,6 +170,9 @@ - `chmod 777 文件名/目录`,给指定文件增加最高权限,系统中的所有人都可以进行读写。 - linux 的权限分为 rwx。r 代表:可读,w 代表:可写,x 代表:可执行 - 这三个权限都可以转换成数值表示,r = 4,w = 2,x = 1,- = 0,所以总和是 7,也就是最大权限。第一个 7 是所属主(user)的权限,第二个 7 是所属组(group)的权限,最后一位 7 是非本群组用户(others)的权限。 + - `chmod -R 777 目录` 表示递归目录下的所有文件夹,都赋予 777 权限 + - `chown myUsername:myGroupName myFile` 表示修改文件所属用户、组 + - `chown -R myUsername:myGroupName myFolder` 表示递归修改指定目录下的所有文件权限 - `su`:切换到 root 用户,终端目录还是原来的地方(常用) - `su -`:切换到 root 用户,其中 **-** 号另起一个终端并切换账号 - `su 用户名`,切换指定用户帐号登陆,终端目录还是原来地方。 @@ -151,7 +180,10 @@ - `exit`,注销当前用户(常用) - `sudo 某个命令`,使用管理员权限使用命令,使用 sudo 回车之后需要输入当前登录账号的密码。(常用) - `passwd`,修改当前用户密码(常用) - +- 添加临时账号,并指定用户根目录,并只有可读权限方法 + - 添加账号并指定根目录(用户名 tempuser):`useradd -d /data/logs -m tempuser` + - 设置密码:`passwd tempuser` 回车设置密码 + - 删除用户(该用户必须退出 SSH 才能删除成功),也会同时删除组:`userdel tempuser` ## 磁盘管理 @@ -169,8 +201,20 @@ - `umount /dev/sdb5`,卸载挂载,用分区名 +## wget 下载文件 + +- 常规下载:`wget http://www.gitnavi.com/index.html` +- 自动断点下载:`wget -c http://www.gitnavi.com/index.html` +- 后台下载:`wget -b http://www.gitnavi.com/index.html` +- 伪装代理名称下载:`wget --user-agent="Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16" http://www.gitnavi.com/index.html` +- 限速下载:`wget --limit-rate=300k http://www.gitnavi.com/index.html` +- 批量下载:`wget -i /opt/download.txt`,一个下载地址一行 +- 后台批量下载:`wget -b -c -i /opt/download.txt`,一个下载地址一行 + + ## 资料 - - +- diff --git a/markdown-file/CI-Install-And-Usage.md b/markdown-file/CI-Install-And-Usage.md new file mode 100644 index 00000000..dd5bbd62 --- /dev/null +++ b/markdown-file/CI-Install-And-Usage.md @@ -0,0 +1,310 @@ + + +# CI 一整套服务 + +## 环境说明 + +- CentOS 7.3 +- 两台机子(一台机子也是可以,内存至少要 8G) + - 一台:Gitlab + Redis + Postgresql + - 硬件推荐:内存 4G + - 端口安排 + - Gitlab:10080 + - 一台:Nexus + Jenkins + SonarQube + Postgresql + - 硬件推荐:内存 8G + - 端口安排 + - SonarQube:19000 + - Nexus:18081 + - Jenkins:18080 + +## Gitlab + Redis + Postgresql + +- 预计会使用内存:2G 左右 +- 这套方案来自(部分内容根据自己情况进行了修改): +- 创建宿主机挂载目录:`mkdir -p /data/docker/gitlab/gitlab /data/docker/gitlab/redis /data/docker/gitlab/postgresql` +- 赋权(避免挂载的时候,一些程序需要容器中的用户的特定权限使用):`chmod -R 777 /data/docker/gitlab/gitlab /data/docker/gitlab/redis /data/docker/gitlab/postgresql` +- 这里使用 docker-compose 的启动方式,所以需要创建 docker-compose.yml 文件: + +```yaml +version: '2' + +services: + redis: + restart: always + image: sameersbn/redis:latest + command: + - --loglevel warning + volumes: + - /data/docker/gitlab/redis:/var/lib/redis:Z + + postgresql: + restart: always + image: sameersbn/postgresql:9.6-2 + volumes: + - /data/docker/gitlab/postgresql:/var/lib/postgresql:Z + environment: + - DB_USER=gitlab + - DB_PASS=password + - DB_NAME=gitlabhq_production + - DB_EXTENSION=pg_trgm + + gitlab: + restart: always + image: sameersbn/gitlab:10.4.2-1 + depends_on: + - redis + - postgresql + ports: + - "10080:80" + - "10022:22" + volumes: + - /data/docker/gitlab/gitlab:/home/git/data:Z + environment: + - DEBUG=false + + - DB_ADAPTER=postgresql + - DB_HOST=postgresql + - DB_PORT=5432 + - DB_USER=gitlab + - DB_PASS=password + - DB_NAME=gitlabhq_production + + - REDIS_HOST=redis + - REDIS_PORT=6379 + + - TZ=Asia/Shanghai + - GITLAB_TIMEZONE=Beijing + + - GITLAB_HTTPS=false + - SSL_SELF_SIGNED=false + + - GITLAB_HOST=192.168.0.105 + - GITLAB_PORT=10080 + - GITLAB_SSH_PORT=10022 + - GITLAB_RELATIVE_URL_ROOT= + - GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alphanumeric-string + - GITLAB_SECRETS_SECRET_KEY_BASE=long-and-random-alphanumeric-string + - GITLAB_SECRETS_OTP_KEY_BASE=long-and-random-alphanumeric-string + + - GITLAB_ROOT_PASSWORD= + - GITLAB_ROOT_EMAIL= + + - GITLAB_NOTIFY_ON_BROKEN_BUILDS=true + - GITLAB_NOTIFY_PUSHER=false + + - GITLAB_EMAIL=notifications@example.com + - GITLAB_EMAIL_REPLY_TO=noreply@example.com + - GITLAB_INCOMING_EMAIL_ADDRESS=reply@example.com + + - GITLAB_BACKUP_SCHEDULE=daily + - GITLAB_BACKUP_TIME=01:00 + + - SMTP_ENABLED=false + - SMTP_DOMAIN=www.example.com + - SMTP_HOST=smtp.gmail.com + - SMTP_PORT=587 + - SMTP_USER=mailer@example.com + - SMTP_PASS=password + - SMTP_STARTTLS=true + - SMTP_AUTHENTICATION=login + + - IMAP_ENABLED=false + - IMAP_HOST=imap.gmail.com + - IMAP_PORT=993 + - IMAP_USER=mailer@example.com + - IMAP_PASS=password + - IMAP_SSL=true + - IMAP_STARTTLS=false + + - OAUTH_ENABLED=false + - OAUTH_AUTO_SIGN_IN_WITH_PROVIDER= + - OAUTH_ALLOW_SSO= + - OAUTH_BLOCK_AUTO_CREATED_USERS=true + - OAUTH_AUTO_LINK_LDAP_USER=false + - OAUTH_AUTO_LINK_SAML_USER=false + - OAUTH_EXTERNAL_PROVIDERS= + + - OAUTH_CAS3_LABEL=cas3 + - OAUTH_CAS3_SERVER= + - OAUTH_CAS3_DISABLE_SSL_VERIFICATION=false + - OAUTH_CAS3_LOGIN_URL=/cas/login + - OAUTH_CAS3_VALIDATE_URL=/cas/p3/serviceValidate + - OAUTH_CAS3_LOGOUT_URL=/cas/logout + + - OAUTH_GOOGLE_API_KEY= + - OAUTH_GOOGLE_APP_SECRET= + - OAUTH_GOOGLE_RESTRICT_DOMAIN= + + - OAUTH_FACEBOOK_API_KEY= + - OAUTH_FACEBOOK_APP_SECRET= + + - OAUTH_TWITTER_API_KEY= + - OAUTH_TWITTER_APP_SECRET= + + - OAUTH_GITHUB_API_KEY= + - OAUTH_GITHUB_APP_SECRET= + - OAUTH_GITHUB_URL= + - OAUTH_GITHUB_VERIFY_SSL= + + - OAUTH_GITLAB_API_KEY= + - OAUTH_GITLAB_APP_SECRET= + + - OAUTH_BITBUCKET_API_KEY= + - OAUTH_BITBUCKET_APP_SECRET= + + - OAUTH_SAML_ASSERTION_CONSUMER_SERVICE_URL= + - OAUTH_SAML_IDP_CERT_FINGERPRINT= + - OAUTH_SAML_IDP_SSO_TARGET_URL= + - OAUTH_SAML_ISSUER= + - OAUTH_SAML_LABEL="Our SAML Provider" + - OAUTH_SAML_NAME_IDENTIFIER_FORMAT=urn:oasis:names:tc:SAML:2.0:nameid-format:transient + - OAUTH_SAML_GROUPS_ATTRIBUTE= + - OAUTH_SAML_EXTERNAL_GROUPS= + - OAUTH_SAML_ATTRIBUTE_STATEMENTS_EMAIL= + - OAUTH_SAML_ATTRIBUTE_STATEMENTS_NAME= + - OAUTH_SAML_ATTRIBUTE_STATEMENTS_FIRST_NAME= + - OAUTH_SAML_ATTRIBUTE_STATEMENTS_LAST_NAME= + + - OAUTH_CROWD_SERVER_URL= + - OAUTH_CROWD_APP_NAME= + - OAUTH_CROWD_APP_PASSWORD= + + - OAUTH_AUTH0_CLIENT_ID= + - OAUTH_AUTH0_CLIENT_SECRET= + - OAUTH_AUTH0_DOMAIN= + + - OAUTH_AZURE_API_KEY= + - OAUTH_AZURE_API_SECRET= + - OAUTH_AZURE_TENANT_ID= +``` + + +- 启动:`docker-compose up -d`,启动比较慢,等个 2 分钟左右。 +- 浏览器访问 Gitlab: + - 默认用户是 root,密码首次访问必须重新设置,并且最小长度为 8 位,我习惯设置为:aa123456 + - 添加 SSH key: +- Gitlab 的具体使用可以看另外文章:[Gitlab 的使用](Gitlab-Install-And-Settings.md) + +## Nexus + Jenkins + SonarQube + +- 预计会使用内存:4G 左右 +- 创建宿主机挂载目录:`mkdir -p /data/docker/ci/nexus /data/docker/ci/jenkins /data/docker/ci/jenkins/lib /data/docker/ci/jenkins/home /data/docker/ci/sonarqube /data/docker/ci/postgresql /data/docker/ci/gatling/results` +- 赋权(避免挂载的时候,一些程序需要容器中的用户的特定权限使用):`chmod -R 777 /data/docker/ci/nexus /data/docker/ci/jenkins/lib /data/docker/ci/jenkins/home /data/docker/ci/sonarqube /data/docker/ci/postgresql /data/docker/ci/gatling/results` +- 下面有一个细节要特别注意:yml 里面不能有中文。还有就是 sonar 的挂载目录不能直接挂在 /opt/sonarqube 上,不然会启动不了。 +- 这里使用 docker-compose 的启动方式,所以需要创建 docker-compose.yml 文件: + +```yaml +version: '3' + +networks: + prodnetwork: + driver: bridge + +services: + sonardb: + image: postgres:9.6.6 + restart: always + ports: + - "5433:5432" + networks: + - prodnetwork + volumes: + - /data/docker/ci/postgresql:/var/lib/postgresql + environment: + - POSTGRES_USER=sonar + - POSTGRES_PASSWORD=sonar + sonar: + image: sonarqube:6.7.1 + restart: always + ports: + - "19000:9000" + - "19092:9092" + networks: + - prodnetwork + depends_on: + - sonardb + volumes: + - /data/docker/ci/sonarqube/conf:/opt/sonarqube/conf + - /data/docker/ci/sonarqube/data:/opt/sonarqube/data + - /data/docker/ci/sonarqube/extension:/opt/sonarqube/extensions + - /data/docker/ci/sonarqube/bundled-plugins:/opt/sonarqube/lib/bundled-plugins + environment: + - SONARQUBE_JDBC_URL=jdbc:postgresql://sonardb:5432/sonar + - SONARQUBE_JDBC_USERNAME=sonar + - SONARQUBE_JDBC_PASSWORD=sonar + nexus: + image: sonatype/nexus3 + restart: always + ports: + - "18081:8081" + networks: + - prodnetwork + volumes: + - /data/docker/ci/nexus:/nexus-data + jenkins: + image: wine6823/jenkins:1.1 + restart: always + ports: + - "18080:8080" + networks: + - prodnetwork + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /usr/bin/docker:/usr/bin/docker + - /etc/localtime:/etc/localtime:ro + - $HOME/.ssh:/root/.ssh + - /data/docker/ci/jenkins/lib:/var/lib/jenkins/ + - /data/docker/ci/jenkins/home:/var/jenkins_home + depends_on: + - nexus + - sonar + environment: + - NEXUS_PORT=8081 + - SONAR_PORT=9000 + - SONAR_DB_PORT=5432 +``` + +- 启动:`docker-compose up -d`,启动比较慢,等个 2 分钟左右。 +- 浏览器访问 SonarQube: + - 默认用户名:admin + - 默认密码:admin + - 插件安装地址: + - 代码检查规范选择: + - 如果没有安装相关检查插件,默认是没有内容可以设置,建议现在插件市场安装 FindBugs,这样也可以帮你生成插件目录:`/extension/plugins` + - 如果你有其他额外插件,可以把 jar 放在 `${SONAR_HOME}/extension/plugins` 目录下,然后重启下 sonar +- 浏览器访问 Nexus: + - 默认用户名:admin + - 默认密码:admin123 +- 浏览器访问 Jenkins: + - 首次进入 Jenkins 的 Web UI 界面是一个解锁页面 Unlock Jenkins,需要让你输入:Administrator password + - 这个密码放在:`/var/jenkins_home/secrets/initialAdminPassword`,你需要先:`docker exec -it ci_jenkins_1 /bin/bash` + - 然后:`cat /var/jenkins_home/secrets/initialAdminPassword`,找到初始化密码 + +--------------------------------- + +## 配置 Jenkins 拉取代码权限 + +- 因为 dockerfile 中我已经把宿主机的 .ssh 下的挂载在 Jenkins 的容器中 +- 所以读取宿主机的 pub:`cat ~/.ssh/id_rsa.pub`,然后配置在 Gitlab 中: +- Jenkinsfile 中 Git URL 使用:ssh 协议,比如:`ssh://git@192.168.0.105:10022/gitnavi/spring-boot-ci-demo.git` + +## Jenkins 特殊配置(减少权限问题,如果是内网的话) + +- 访问: + - 去掉 `防止跨站点请求伪造` + - 勾选 `登录用户可以做任何事` 下面的:`Allow anonymous read access` + + +## 配置 Gitlab Webhook + +- Jenkins 访问: + - 在 `Build Triggers` 勾选:`触发远程构建 (例如,使用脚本)`,在 `身份验证令牌` 输入框填写任意字符串,这个等下 Gitlab 会用到,假设我这里填写:112233 +- Gitlab 访问: + - 在 `URL` 中填写:`http://192.168.0.105:18080/job/任务名/build?token=112233` + + + + +## 资料 + +- diff --git a/markdown-file/CentOS-7-Install.md b/markdown-file/CentOS-7-Install.md new file mode 100644 index 00000000..c9428617 --- /dev/null +++ b/markdown-file/CentOS-7-Install.md @@ -0,0 +1,70 @@ +# CentOS 7 安装 + + +## 概括 + +- 本教程中主要演示了 VMware Workstation 下安装 `CentOS 7.3` 的过程。 +- VMware 的使用细节可以看这篇:[CentOS 6 安装](CentOS-Install.md) +- 如果你是要安装到 PC 机中,你需要准备一个 U 盘,以及 Windows 下载这个软件:[USBWriter(提取码:5aa2)](https://pan.baidu.com/s/1gg83h9T) +- 如果你是要安装到 PC 机中,你需要准备一个 U 盘,以及 macOS 下载这个软件:[balenaEtcher(提取码:oqp9)](https://pan.baidu.com/s/1l5K48tfuCKdn0wR_62PjJA) +- USBWriter 的使用很简单,如下图即可制作一个 CentOS 系统盘 + +![VMware 下安装](../images/CentOS-7-Install-a-0.jpg) + + +## VMware 下安装 CentOS 过程 + +- VMware Workstation 的介绍和下载 + - 官网: + - wiki: + - 百度 wiki: + - 百度云下载(64 位): + - 官网下载: + + +- 安装细节开始: + +![VMware 下安装](../images/CentOS-7-Install-a-1.jpg) + +![VMware 下安装](../images/CentOS-7-Install-a-2.jpg) + +![VMware 下安装](../images/CentOS-7-Install-a-3.jpg) + +![VMware 下安装](../images/CentOS-7-Install-a-4.jpg) + +![VMware 下安装](../images/CentOS-7-Install-a-5.jpg) + +- 如上图,默认是最小安装,点击进去,选择桌面安装。 +- 如上图,默认是自动分区,如果懂得分区,点击进去,进行手动分区,CentOS 7 少了主分区,逻辑分区的选择了。 + +![VMware 下安装](../images/CentOS-7-Install-a-6.jpg) + +- 如上图,root 密码必须设置,我习惯测试的时候是:123456 +- 我没有创建用户,喜欢用 root + +![VMware 下安装](../images/CentOS-7-Install-a-7.jpg) + +![VMware 下安装](../images/CentOS-7-Install-a-8.jpg) + +- 如上图,许可证必须点击进去勾选同意相关协议。 +- 如上图,网络可以稍后在设置,主机名可以现在先填写 + +![VMware 下安装](../images/CentOS-7-Install-a-9.jpg) + +![VMware 下安装](../images/CentOS-7-Install-a-10.jpg) + +![VMware 下安装](../images/CentOS-7-Install-a-11.jpg) + +![VMware 下安装](../images/CentOS-7-Install-a-12.jpg) + +- 如上图右上角,一般我们都选择跳过 + +![VMware 下安装](../images/CentOS-7-Install-a-13.jpg) + +![VMware 下安装](../images/CentOS-7-Install-a-14.jpg) + +![VMware 下安装](../images/CentOS-7-Install-a-15.jpg) + +![VMware 下安装](../images/CentOS-7-Install-a-16.jpg) + +- 到此完成,其他该做啥就做啥 diff --git a/markdown-file/CentOS-Install.md b/markdown-file/CentOS-Install.md new file mode 100644 index 00000000..94b02c01 --- /dev/null +++ b/markdown-file/CentOS-Install.md @@ -0,0 +1,121 @@ +# CentOS 安装 + + +## 概括 + +- 本教程中主要演示了 VirtualBox 和 VMware Workstation 下安装 `CentOS 6.6` 的过程。 +- VirtualBox 是免费开源,我个人在使用经历中遇到过很多次崩溃、安装有问题等,所以它不是我主推的虚拟机 +- VMware Workstation 是商业软件,很好用,一些辅助功能也很到位,主推该虚拟机。 +- 如果你是要安装到 PC 机中,你需要准备一个 U 盘,以及下载这个软件:[USBWriter(提取码:5aa2)](https://pan.baidu.com/s/1gg83h9T) +- USBWriter 的使用很简单,如下图即可制作一个 CentOS 系统盘 + +![VMware 下安装](../images/CentOS-7-Install-a-0.jpg) + +## VirtualBox 下安装 CentOS 过程 + +- VirtualBox 的介绍和下载 +- 官网: +- wiki: +- 百度 wiki: +- 百度云下载(32 位和 64 位一体): +- 官网下载: + + +#### VirtualBox 安装细节开始: + +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-1.jpg) +- 如上图标注 1 所示:点击 `新建` 一个虚拟机。 +- 如上图标注 2 所示:在填写 `名称` 的时候,输入 `CentOS` 相关字眼的时候,下面的版本类型会跟着变化,自动识别为 `Red Hat` +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-2.jpg) +- 如上图标注 1 所示:我们装的是 64 位系统,如果你本机内存足够大,建议可以给 2 ~ 4 G 的容量 +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-3.jpg) +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-4.jpg) +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-5.jpg) +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-6.jpg) +- 如上图所示,命名最好规范,最好要带上系统版本号,硬盘大小建议在 8 ~ 20 G +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-b-1.gif) +- 如上图 gif 演示,当我们创建好虚拟机之后,需要选择模拟光驱进行系统镜像安装 +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-7.jpg) +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-8.jpg) +- 如上图箭头所示,我们这里选择 `Skip`,跳过对镜像的检查,这个一般需要检查很久,而且我们用 iso 文件安装的,一般没这个必要 +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-9.jpg) +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-12.jpg) +- 如上图标注 1 所示,建议 Linux 纯新手使用简体中文环境 +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-13.jpg) +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-14.jpg) +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-15.jpg) +- 如上图标注 1 所示,因为我们是用全新的虚拟机,虚拟出来的硬盘都是空的,所以这里可以忽略所有数据 +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-16.jpg) +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-17.jpg) +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-18.jpg) +- 再次强调下,root 账号也就是图上所说的 `根账号`,它是最顶级账号,密码最好别忘记了 +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-19.jpg) +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-20.jpg) +- 如上图标注 1 所示,因为我们是用全新的虚拟机,所以这里选择 `使用所有空间` ,然后 CentOS 会按它默认的方式进行分区 +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-21.jpg) +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-22.jpg) +- `Desktop` 代表:图形界面版,会默认安装很多软件,建议新手选择此模式,我后面其他文章的讲解都是基于此系统下,如果你不是此模式的系统可能在安装某些软件的时候会出现某些依赖包没有安装的情况 +- `basic sever` 代表:命令行界面,有良好基础的基本都会喜欢这个 +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-23.jpg) +- 上一步我选择的是 `Desktop` 所以有很多软件需要安装,这个过程大概需要 5 ~ 10 分钟 +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-24.jpg) +- 安装完成 +- ![VirtualBox 下安装](../images/CentOS-Install-VirtualBox-a-25.jpg) +- 安装完成后一定要把盘片删除,防止系统启动的时候去读盘,重新进入安装系统模式 + + +## VMware 下安装 CentOS 过程 + +- VMware Workstation 的介绍和下载 +- 官网: +- wiki: +- 百度 wiki: +- 百度云下载(64 位): +- 官网下载: + + +#### VMware 安装细节开始: + +- ![VMware 下安装](../images/CentOS-install-VMware-a-1.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-a-2.jpg) +- 默认 VMware 选择的是 `典型` 我不推荐,我下面的步骤是选择 `自定义(高级)`。如果你非常了解 Linux 系统倒是可以考虑选择 `典型`,在它默认安装完的系统上可以很好地按你的需求进行修改 +- ![VMware 下安装](../images/CentOS-install-VMware-a-3.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-a-4.jpg) +- 牢记:不要在这一步就选择镜像文件,不然也会直接进入 `典型` 模式,直接按它的规则进行系统安装 +- ![VMware 下安装](../images/CentOS-install-VMware-a-5.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-a-6.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-a-7.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-a-8.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-a-9.jpg) +- 桥接模式:(建议选择此模式)创建一个独立的虚拟主机,在桥接模式下的虚拟主机网络一般要为其配 IP 地址、子网掩码、默认网关(虚拟机ip地址要与主机ip地址处于同网段) +- NAT 模式:把物理主机作为路由器进行访问互联网,优势:联网简单,劣势:虚拟主机无法与物理主机通讯 +- 主机模式:把虚拟主机网络与真实网络隔开,但是各个虚拟机之间可以互相连接,虚拟机和物理机也可以连接 +- > 上面解释来源: +- ![VMware 下安装](../images/CentOS-install-VMware-a-10.jpg) +- Buslogic 和 LSIlogic 都是虚拟硬盘 SCSI 设备的类型,旧版本的 OS 默认的是 Buslogic,LSIlogic 类型的硬盘改进了性能,对于小文件的读取速度有提高,支持非 SCSI 硬盘比较好。 +- > 上面解释来源: +- ![VMware 下安装](../images/CentOS-install-VMware-a-11.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-a-12.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-a-13.jpg) +- 强烈建议至少要给 20 G,不然装不了多少软件的 +- ![VMware 下安装](../images/CentOS-install-VMware-a-14.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-a-15.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-b-1.gif) +- 如上图 gif 所示,在创建完虚拟机之后,我们要加载系统镜像,然后启动虚拟机进行安装,接下来的安装步骤跟上面使用 VirtualBox 安装细节基本一样,不一样的地方是我这里选择的是自定义分区,不再是选择默认分区方式 +- ![VMware 下安装](../images/CentOS-install-VMware-a-16.jpg) +- 如上图箭头所示,这里我们选择自定义分区方式 +- ![VMware 下安装](../images/CentOS-install-VMware-b-2.gif) +- 如上图 gif 所示,我只把最基本的区分出来,如果你有自己的需求可以自己设置 +- 简单分区方案: + - `/boot` == 500 M(主分区) + - `/swap` == 2 G(逻辑分区)一般大家的说法这个大小是跟你机子的内存大小相关的,也有说法内存大不需要这个,但是还是建议分,虚拟机内存 2 G,所以我分 2 G + - `/` == 剩余容量(逻辑分区)剩余的空间都给了根分区 +- ![VMware 下安装](../images/CentOS-install-VMware-a-17.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-a-18.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-a-19.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-a-20.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-a-21.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-a-22.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-a-23.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-a-24.jpg) +- ![VMware 下安装](../images/CentOS-install-VMware-a-25.jpg) diff --git a/CentOS-Virtual-Machine-Copy-Settings.md b/markdown-file/CentOS-Virtual-Machine-Copy-Settings.md similarity index 79% rename from CentOS-Virtual-Machine-Copy-Settings.md rename to markdown-file/CentOS-Virtual-Machine-Copy-Settings.md index d94c8fef..3cdbd8f2 100644 --- a/CentOS-Virtual-Machine-Copy-Settings.md +++ b/markdown-file/CentOS-Virtual-Machine-Copy-Settings.md @@ -4,12 +4,13 @@ - 在我们需要多台 CentOS 虚拟机的时候,对已有虚拟机的系统进行克隆或是复制。但是这样做又有一个问题,克隆出来的虚拟机启动的时候你输入命令:`ifconfig`,eth0 网卡信息没了,只有一个 eth1。 对于处女座的人来讲这是不允许的。所以我们需要改动下。 - 复制虚拟机后,首次打开该会提示如下内容,一般选择 copy 这个配置。 - - ![vim](images/CentOS-Virtual-Machine-Copy-Settings-a-1.png) + - ![vim](../images/CentOS-Virtual-Machine-Copy-Settings-a-1.png) -## 修改方法 +## CentOS 6 修改方法 +- 设置 hostname:`hostnamectl --static set-hostname linux02` - 命令:`sudo vim /etc/udev/rules.d/70-persistent-net.rules` - 该文件中正常此时应该有两行信息 - 在文件中把 NAME="eth0″ 的这一行注释掉 @@ -23,4 +24,10 @@ - 如果显示两行 UUID 的信息的话,复制不是 System eth0 的那个 UUID 值,下面有用。 - 编辑:`sudo vim /etc/sysconfig/network-scripts/ifcfg-eth0` - 把文件中的 UUID 值 改为上面要求复制的 UUID 值。 - - 保存配置文件,重启系统,正常应该是可以了。 \ No newline at end of file + - 保存配置文件,重启系统,正常应该是可以了。 + +## CentOS 7 修改方法 + +- 在 VMware 15 Pro 的情况下,直接 copy 进行后,直接修改网卡配置即可 +- 编辑该文件:`vim /etc/sysconfig/network-scripts/ifcfg-ens33` + - 把 ip 地址修改即可 \ No newline at end of file diff --git a/CentOS.md b/markdown-file/CentOS.md similarity index 100% rename from CentOS.md rename to markdown-file/CentOS.md diff --git a/CentOS6-and-CentOS7.md b/markdown-file/CentOS6-and-CentOS7.md similarity index 84% rename from CentOS6-and-CentOS7.md rename to markdown-file/CentOS6-and-CentOS7.md index 2ca72919..7dd26640 100644 --- a/CentOS6-and-CentOS7.md +++ b/markdown-file/CentOS6-and-CentOS7.md @@ -2,7 +2,7 @@ ## 总体差异 -- ![总体差异](images/CentOS6-and-CentOS7-a-1.png) +- ![总体差异](../images/CentOS6-and-CentOS7-a-1.png) ## 想装回过去的一些工具 @@ -36,7 +36,12 @@ ### 开放端口 -- 添加端口:`firewall-cmd --zone=public --add-port=8883/tcp --permanent` +- 一般设置软件端口有一个原则: + - 0 ~ 1024 系统保留,一般不要用到 + - 1024 ~ 65535(2^16) 可以随意用 +- 添加单个端口:`firewall-cmd --zone=public --add-port=8883/tcp --permanent` +- 添加范围端口:`firewall-cmd --zone=public --add-port=8883-8885/tcp --permanent` +- 删除端口:`firewall-cmd --zone=public --remove-port=8883/tcp --permanent` - 重启防火墙:`firewall-cmd --reload` - 命令解释: - `--zone` #作用域 diff --git a/markdown-file/Confluence-Install-And-Settings.md b/markdown-file/Confluence-Install-And-Settings.md new file mode 100644 index 00000000..5a1a6fe1 --- /dev/null +++ b/markdown-file/Confluence-Install-And-Settings.md @@ -0,0 +1,134 @@ +# Confluence 安装和配置 + +## Confluence 6.15.4 + +- 最新 6.15.4 版本时间:2019-05 + +#### 数据库 + +``` +docker run \ + --name mysql-confluence \ + --restart always \ + -p 3316:3306 \ + -e MYSQL_ROOT_PASSWORD=adg123456 \ + -e MYSQL_DATABASE=confluence_db \ + -e MYSQL_USER=confluence_user \ + -e MYSQL_PASSWORD=confluence_123456 \ + -d \ + mysql:5.7 +``` + +- 连上容器:`docker exec -it mysql-confluence /bin/bash` + - 连上 MySQL:`mysql -u root -p` +- 设置编码: + - **必须做这一步,不然配置过程会报错,confluence 的 DB 要求是 utf8,还不能是 utf8mb4** + - **并且排序规则还必须是:utf8_bin** + - **数据库必须使用'READ-COMMITTED'作为默认隔离级别** + +``` +SET NAMES 'utf8'; +alter database confluence_db character set utf8 collate utf8_bin; +SET GLOBAL tx_isolation='READ-COMMITTED'; +``` + +#### 安装 + +- 下载: + - 选择:linux64 类型下载 +- 授权:`chmod +x atlassian-confluence-6.15.4-x64.bin` + + +``` +./atlassian-confluence-6.15.4-x64.bin + +开始提示: + +Unpacking JRE ... +Starting Installer ... + +This will install Confluence 6.9.0 on your computer. +OK [o, Enter], Cancel [c] + +>> 输入o或直接回车 + +Click Next to continue, or Cancel to exit Setup. + +Choose the appropriate installation or upgrade option. +Please choose one of the following: +Express Install (uses default settings) [1], +Custom Install (recommended for advanced users) [2, Enter], +Upgrade an existing Confluence installation [3] +1 +>> 这里输入数字1 + +See where Confluence will be installed and the settings that will be used. +Installation Directory: /opt/atlassian/confluence +Home Directory: /var/atlassian/application-data/confluence +HTTP Port: 8090 +RMI Port: 8000 +Install as service: Yes +Install [i, Enter], Exit [e] +i + +>> 输入i或者直接回车 + +Extracting files ... + +Please wait a few moments while we configure Confluence. + +Installation of Confluence 6.9.0 is complete +Start Confluence now? +Yes [y, Enter], No [n] + +>> 输入y或者直接回车 + +Please wait a few moments while Confluence starts up. +Launching Confluence ... + +Installation of Confluence 6.9.0 is complete +Your installation of Confluence 6.9.0 is now ready and can be accessed via +your browser. +Confluence 6.9.0 can be accessed at http://localhost:8090 +Finishing installation ... + +# 安装完成,访问本机的8090端口进行web端安装 +# 开放防火墙端口 +firewall-cmd --add-port=8090/tcp --permanent +firewall-cmd --add-port=8000/tcp --permanent +firewall-cmd --reload +``` + +- 默认是安装在 /opt 目录下:`/opt/atlassian/confluence/confluence/WEB-INF/lib` +- 启动:`sh /opt/atlassian/confluence/bin/start-confluence.sh` +- 停止:`sh /opt/atlassian/confluence/bin/stop-confluence.sh` +- 查看 log:`tail -300f /opt/atlassian/confluence/logs/catalina.out` +- 卸载:`sh /opt/atlassian/confluence/uninstall` +- 设置 MySQL 连接驱动,把 mysql-connector-java-5.1.47.jar 放在目录 `/opt/atlassian/confluence/confluence/WEB-INF/lib` + +#### 首次配置 + +- 访问: +- 参考文章: +- 参考文章: +- 因为步骤一样,所以我就不再截图了。 + +#### License 过程 + +- 参考自己的为知笔记 + + +## 反向代理的配置可以参考 + +- + + +## 使用 markdown + +- 点击右上角小齿轮 > 管理应用 > 搜索市场应用 > 输入 markdown > 安装 + + +## 其他资料 + +- +- diff --git a/markdown-file/Crontab.md b/markdown-file/Crontab.md new file mode 100644 index 00000000..2bb88205 --- /dev/null +++ b/markdown-file/Crontab.md @@ -0,0 +1,62 @@ +# Crontab 介绍 + + +## Crontab 安装 + +- 查看是否已安装: + - CentOS:`rpm -qa | grep cron` + - Ubuntu:`dpkg -l | grep cron` + +- 安装(一般系统是集成的): + - CentOS 6 / 7:`sudo yum install -y vixie-cron crontabs` + - Ubuntu:`sudo apt-get install -y cron` + +- 服务常用命令 + - CentOS 6 + - `service crond start` 启动服务 + - `service crond stop` 关闭服务 + - `service crond restart` 重启服务 + - CentOS 7 + - `systemctl start crond` 启动服务 + - `systemctl restart crond` 重新启动服务 + - `systemctl status crond` 加入自启动 + - `systemctl stop crond` 关闭服务 + + +## Crontab 服务器配置文件常用参数 + +- 配置文件介绍(记得先备份):`sudo vim /etc/crontab` +- 注意:不要在配置文件里面写相对路径 + - 该配置格式解释: + - ![Crontab 服务器配置文件常用参数](../images/Crontab-a-1.jpg) + - 常用例子介绍: + - `30 21 * * * service httpd restart` #每晚的 21:30 重启 apache + - `30 21 * * 6,0 service httpd restart` #每周六、周日的 21:30 重启 apache + - `45 4 1,10,22 * * service httpd restart` #每月的 1、10、22 日的 4:45 重启 apache + - `45 4 1-10 * * service httpd restart` #每月的 1 到 10 日的 4:45 重启 apache + - `*/2 * * * * service httpd restart` #每隔两分钟重启 apache + - `1-59/2 * * * * service httpd restart` #每隔两分钟重启 apache(这个比较特殊:1-59/2 这个表示过掉0分,从 1 分开始算,每隔两分执行,所以 1 分执行了,3 分执行了,5 分执行了....都是奇数进行执行。默认的 */2 都是偶数执行。) + - `* */2 * * * service httpd restart` #每隔两小时重启 apache + - `0 23-7/2 * * * service httpd restart` #晚上 11 点到早上 7 点之间,每隔 2 个小时重启 apache + - `0-59/30 18-23 * * * service httpd restart` #每天 18:00 到 23:00 之间,每隔 30 分钟重启 apache(方法一) + - `0,30 18-23 * * * service httpd restart` #每天 18:00 到 23:00 之间,每隔 30 分钟重启 apache(方法二) + - `0 4 * * sun root /opt/shell/crontab-redis-restart.sh` #每周日 4:00 执行一个脚本(root 用户运行,有些脚本不指定用户会报:ERROR (getpwnam() failed) +- 更多例子可以看: +- 执行记录日志:`tail -f /var/log/cron`(如果发现任务不执行,可以来这里盯着日志看) + + +## Crontab 权限问题 + +- 一般默认只有 root 用户可以使用 +- 如果要指定某个用户可以使用,可以在 /etc/cron.allow 添加(不存在文件就创建一个) +- 如果要指定某个用户不可以使用,可以在 /etc/cron.deny 添加(不存在文件就创建一个) +- 如果一个用户同时在两个文件都存在,那则以 allow 为准 + +## Crontab 不执行 + +- Crontab 不执行原因有很多,可以 Google 搜索:`Crontab 不执行`,这里不多说。 + +## Crontab 资料 + +- +- diff --git a/Daemontools.md b/markdown-file/Daemontools.md similarity index 92% rename from Daemontools.md rename to markdown-file/Daemontools.md index 97cc341f..130ef7dc 100644 --- a/Daemontools.md +++ b/markdown-file/Daemontools.md @@ -49,8 +49,7 @@ python setup.py install ``` -- 生成配置文件: - - `echo_supervisord_conf > /etc/supervisord.conf` +- 生成配置文件:`echo_supervisord_conf > /etc/supervisord.conf` - 创建专门的程序配置文件目录、日志目录: - `mkdir -p /var/log/supervisor` - `mkdir -p /etc/supervisor/conf.d/` @@ -74,17 +73,22 @@ stdout_logfile=/var/log/supervisor/supervisord-logstash.log stderr_logfile=/var/log/supervisor/supervisord-logstash-err.log user=root autostart=true -autorestart=true +autorestart=false startsecs=5 priority=1 stopasgroup=true killasgroup=true ``` +- 该配置的具体说明可以参考:[使用 supervisor 管理进程](http://liyangliang.me/posts/2015/06/using-supervisor/) - 启动程序(默认会启动所有子任务):`/usr/bin/supervisord -c /etc/supervisord.conf` - 管理子任务的命令: + - 子任务状态:`/usr/bin/supervisorctl status` - 启动所有子任务:`/usr/bin/supervisorctl start all` - 结束所有子任务:`/usr/bin/supervisorctl stop all` + - 启动指定子任务:`/usr/bin/supervisorctl start gitnavi-logstash` + - 结束指定子任务:`/usr/bin/supervisorctl stop gitnavi-logstash` + - 重启指定子任务:`/usr/bin/supervisorctl restart gitnavi-logstash` - 只载入最新的配置文件, 并不重启任何进程:`/usr/bin/supervisorctl reread` - 载入最新的配置文件,停止原来的所有进程并按新的配置启动管理所有进程:`/usr/bin/supervisorctl reload` - 根据最新的配置文件,启动新配置或有改动的进程,配置没有改动的进程不会受影响而重启:`/usr/bin/supervisorctl update` diff --git a/markdown-file/Docker-Install-And-Usage.md b/markdown-file/Docker-Install-And-Usage.md new file mode 100644 index 00000000..734c11de --- /dev/null +++ b/markdown-file/Docker-Install-And-Usage.md @@ -0,0 +1,839 @@ + + +# Docker 使用 + +## 环境说明 + +- CentOS 7.3(不准确地说:要求必须是 CentOS 7 64位) +- 不建议在 Windows 上使用 + +## Docker 基本概念 + +- 官网: +- 宿主机:安装 Docker 的那台电脑 +- Docker:一个虚拟化软件,你可以认为是类似:VMware、Virtualbox +- 镜像:可以认为是类似 Windows 下的:XXXX.iso +- 容器:容器为镜像的实例,可以认为是 Virtualbox 运行 XXXX.iso 后的效果 +- 官网的镜像仓库地址: +- 对开发来讲总结一个最简单的说法:在 Maven 未产生的年代,jar 包要随着开发项目走到哪里跟到哪里。有了 Maven 写好 pom.xml 即可。此时的 Docker 就好比如 Maven,帮你省去了开发过程中的部署环境差异,你再也不能随便说:你的系统可以运行,我的系统就不行。现在别人连系统都帮你做好了。 +- 玩法理念:单进程,一个容器最好最专注去做一个事情。虽然它可以既装 MySQL,又装 Nginx 等等,但是让一个容器只做好一件事是最合适的。 +- 其他通俗解释: + +> Docker的思想来自于集装箱,集装箱解决了什么问题?在一艘大船上,可以把货物规整的摆放起来。并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响。那么我就不需要专门运送水果的船和专门运送化学品的船了。只要这些货物在集装箱里封装的好好的,那我就可以用一艘大船把他们都运走。 + docker就是类似的理念。现在都流行云计算了,云计算就好比大货轮。docker就是集装箱。 + 1.不同的应用程序可能会有不同的应用环境,比如.net开发的网站和php开发的网站依赖的软件就不一样,如果把他们依赖的软件都安装在一个服务器上就要调试很久,而且很麻烦,还会造成一些冲突。比如IIS和Apache访问端口冲突。这个时候你就要隔离.net开发的网站和php开发的网站。常规来讲,我们可以在服务器上创建不同的虚拟机在不同的虚拟机上放置不同的应用,但是虚拟机开销比较高。docker可以实现虚拟机隔离应用环境的功能,并且开销比虚拟机小,小就意味着省钱了。 + 2.你开发软件的时候用的是Ubuntu,但是运维管理的都是centos,运维在把你的软件从开发环境转移到生产环境的时候就会遇到一些Ubuntu转centos的问题,比如:有个特殊版本的数据库,只有Ubuntu支持,centos不支持,在转移的过程当中运维就得想办法解决这样的问题。这时候要是有docker你就可以把开发环境直接封装转移给运维,运维直接部署你给他的docker就可以了。而且部署速度快。 + 3.在服务器负载方面,如果你单独开一个虚拟机,那么虚拟机会占用空闲内存的,docker部署的话,这些内存就会利用起来。 + 总之docker就是集装箱原理。 + +- Docker 的优点: +- 持续部署与测试 + +> Docker在开发与运维的世界中具有极大的吸引力,因为它能保持跨环境的一致性。在开发与发布的生命周期中,不同的环境具有细微的不同,这些差异可能是由于不同安装包的版本和依赖关系引起的。然而,Docker可以通过确保从开发到产品发布整个过程环境的一致性来解决这个问题。 + Docker容器通过相关配置,保持容器内部所有的配置和依赖关系始终不变。最终,你可以在开发到产品发布的整个过程中使用相同的容器来确保没有任何差异或者人工干预。 + 使用Docker,你还可以确保开发者不需要配置完全相同的产品环境,他们可以在他们自己的系统上通过VirtualBox建立虚拟机来运行Docker容器。Docker的魅力在于它同样可以让你在亚马逊EC2实例上运行相同的容器。如果你需要在一个产品发布周期中完成一次升级,你可以很容易地将需要变更的东西放到Docker容器中,测试它们,并且使你已经存在的容器执行相同的变更。这种灵活性就是使用Docker的一个主要好处。和标准部署与集成过程一样,Docker可以让你构建、测试和发布镜像,这个镜像可以跨多个服务器进行部署。哪怕安装一个新的安全补丁,整个过程也是一样的。你可以安装补丁,然后测试它,并且将这个补丁发布到产品中。 + +- 环境标准化和版本控制 + +> Docker容器可以在不同的开发与产品发布生命周期中确保一致性,进而标准化你的环境。除此之外,Docker容器还可以像git仓库一样,可以让你提交变更到Docker镜像中并通过不同的版本来管理它们。设想如果你因为完成了一个组件的升级而导致你整个环境都损坏了,Docker可以让你轻松地回滚到这个镜像的前一个版本。这整个过程可以在几分钟内完成,如果和虚拟机的备份或者镜像创建流程对比,那Docker算相当快的,它可以让你快速地进行复制和实现冗余。此外,启动Docker就和运行一个进程一样快。 + +- 隔离性 + +> Docker可以确保你的应用程序与资源是分隔开的。几个月前,Gartner发表了一篇报告,这份报告说明了运行Docker 容器进行资源隔离的效果和虚拟机(VM)管理程序一样的好,但是管理与控制方面还需要进行完善。我们考虑这样一个场景,你在你的虚拟机中运行了很多应用程序,这些应用程序包括团队协作软件(例如Confluence)、问题追踪软件(例如JIRA)、集中身份管理系统(例如Crowd)等等。由于这些软件运行在不同的端口上,所以你必须使用Apache或者Nginx来做反向代理。到目前为止,一切都很正常,但是随着你的环境向前推进,你需要在你现有的环境中配置一个内容管理系统(例如Alfresco)。这时候有个问题发生了,这个软件需要一个不同版本的Apache Tomcat,为了满足这个需求,你只能将你现有的软件迁移到另一个版本的Tomcat上,或者找到适合你现有Tomcat的内容管理系统(Alfresco)版本。对于上述场景,使用Docker就不用做这些事情了。Docker能够确保每个容器都拥有自己的资源,并且和其他容器是隔离的。你可以用不同的容器来运行使用不同堆栈的应用程序。除此之外,如果你想在服务器上直接删除一些应用程序是比较困难的,因为这样可能引发依赖关系冲突。而Docker可以帮你确保应用程序被完全清除,因为不同的应用程序运行在不同的容器上,如果你不在需要一款应用程序,那你可以简单地通过删除容器来删除这个应用程序,并且在你的宿主机操作系统上不会留下任何的临时文件或者配置文件。除了上述好处,Docker还能确保每个应用程序只使用分配给它的资源(包括CPU、内存和磁盘空间)。一个特殊的软件将不会使用你全部的可用资源,要不然这将导致性能降低,甚至让其他应用程序完全停止工作。 + +- 安全性 + +> 如上所述,Gartner也承认Docker正在快速地发展。从安全角度来看,Docker确保运行在容器中的应用程序和其他容器中的应用程序是完全分隔与隔离的,在通信流量和管理上赋予你完全的控制权。Docker容器不能窥视运行在其他容器中的进程。从体系结构角度来看,每个容器只使用着自己的资源(从进程到网络堆栈)。作为紧固安全的一种手段,Docker将宿主机操作系统上的敏感挂载点(例如/proc和/sys)作为只读挂载点,并且使用一种写时复制系统来确保容器不能读取其他容器的数据。Docker也限制了宿主机操作系统上的一些系统调用,并且和SELinux与AppArmor一起运行的很好。此外,在Docker Hub上可以使用的Docker镜像都通过数字签名来确保其可靠性。由于Docker容器是隔离的,并且资源是受限制的,所以即使你其中一个应用程序被黑,也不会影响运行在其它Docker容器上的应用程序。 + +- 多云平台 + +> Docker最大的好处之一就是可移植性。在过去的几年里,所有主流的云计算提供商,包括亚马逊AWS和谷歌的GCP,都将Docker融入到他们的平台并增加了各自的支持。Docker容器能运行在亚马逊的EC2实例、谷歌的GCP实例、Rackspace服务器或者VirtualBox这些提供主机操作系统的平台上。举例来说,如果运行在亚马逊EC2实例上的Docker容器能够很容易地移植到其他几个平台上,比如说VirtualBox,并且达到类似的一致性和功能性,那这将允许你从基础设施层中抽象出来。除了AWS和GCP,Docker在其他不同的IaaS提供商也运行的非常好,例如微软的Azure、OpenStack和可以被具有不同配置的管理者所使用的Chef、Puppet、Ansible等。 + + +## Docker 安装和基本配置 + +- 主要有两个版本: + +> **Docker Enterprise Edition (Docker EE)** is designed for enterprise development and IT teams who build, ship, and run business critical applications in production at scale. Docker EE is integrated, certified, and supported to provide enterprises with the most secure container platform in the industry to modernize all applications. For more information about Docker EE, including purchasing options, see Docker Enterprise Edition. +**Docker Community Edition (Docker CE)** is ideal for developers and small teams looking to get started with Docker and experimenting with container-based apps. Docker CE is available on many platforms, from desktop to cloud to server. Docker CE is available for macOS and Windows and provides a native experience to help you focus on learning Docker. You can build and share containers and automate the development pipeline all from a single environment. +Docker CE has both stable and edge channels. + Stable builds are released once per quarter and are supported for 4 months. + Edge builds are released once per month, and are supported for that month only. If you subscribe to the Edge channel on Linux distributions, you should also subscribe to the Stable channel. + + +- 官网总的安装手册: +- 官网 CentOS 安装手册: +- 目前也支持 Windows,特别是 Windows 10,直接官网一个安装包即可搞定。 +- Windows 10 的 Docker 安装说明: +- 我这里选择 Docker CE 版本: +- CentOS 安装过程: + - `sudo yum install -y yum-utils device-mapper-persistent-data lvm2` + - 添加 repo(可能网络会很慢,有时候会报:Timeout,所以要多试几次) + - `sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo` + - `sudo yum makecache fast` + - `sudo yum install -y docker-ce`,大小:19M,速度很慢。 +- 查看配置文件位置:`systemctl show --property=FragmentPath docker` +- 启动 Docker:`systemctl start docker.service` +- 停止 Docker:`systemctl stop docker.service` +- 查看状态:`systemctl status docker.service` +- 运行 hello world 镜像:`sudo docker run hello-world` + - 因为是第一次使用,所以没这个镜像,需要一个下载过程,所以需要几分钟,可能还会报:Timeout。 + - 镜像自动下载好后会输出这样一段内容,表示已经正常安装并可用了: + + ``` bash + Unable to find image 'hello-world:latest' locally + latest: Pulling from library/hello-world + 78445dd45222: Pull complete + Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7 + Status: Downloaded newer image for hello-world:latest + + Hello from Docker! + This message shows that your installation appears to be working correctly. + + To generate this message, Docker took the following steps: + 1. The Docker client contacted the Docker daemon. + 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. + 3. The Docker daemon created a new container from that image which runs the + executable that produces the output you are currently reading. + 4. The Docker daemon streamed that output to the Docker client, which sent it + to your terminal. + + To try something more ambitious, you can run an Ubuntu container with: + $ docker run -it ubuntu bash + + Share images, automate workflows, and more with a free Docker ID: + https://cloud.docker.com/ + + For more examples and ideas, visit: + https://docs.docker.com/engine/userguide/ + ``` + + +## 镜像加速 + +- 只要是外国的东西在国内基本都很难有好的速度,所有就有了加速器的概念,目前国内常用的如下: +- 阿里云: +- USTC: +- daocloud: +- 网易: +- 时速云: +- 灵雀云: +- 推荐优先阿里云,然后是 USTC +- 我下面的讲解也是基于阿里云加速 +- 阿里云的服务需要注册账号,**首次使用需要设置 docker 登录密码(阿里云叫做:**修改Registry登录密码**),这个以后用私人仓库会用到。** + - 如果忘记了,后面可以在这里修改: + - 注册后请访问:,你会看到专属的加速地址,比如我是:`https://ldhc17y9.mirror.aliyuncs.com`,所以下面文章你看到该地址都表示是这个专属地址,请记得自己更换自己的。 + - 以及教你如何使用 Docker 加速器。如果你已经安装了最新版的 Docker 你就不需要用它的脚本进行安装了。 +- 最新版本的 Docker 是新增配置文件:`vim /etc/docker/daemon.json`,增加如下内容: + +``` bash +{ + "registry-mirrors": ["https://ldhc17y9.mirror.aliyuncs.com"] +} +``` + +- `sudo systemctl daemon-reload` +- `sudo systemctl restart docker` +- 在以后的生活中如果要经常使用阿里云做为自己仓库,那你还需要做: + - 在 ` namespace管理` 中创建属于你自己的 namespace: + - 创建镜像仓库: + - 创建好仓库后,点击:`管理` 进入查看仓库的更多详细信息,这里面有很多有用的信息,包括一个详细的操作指南,**这份指南等下会用到。** + - 比如我自己创建一个 redis-to-cluster 仓库,地址是阿里云给我们的:`registry.cn-shenzhen.aliyuncs.com/youmeek/redis-to-cluster` + - 那我登录这个镜像地址的方式: + +``` +docker login registry.cn-shenzhen.aliyuncs.com +会让我输入 +Username:阿里云邮箱 +password:上文提到的--Registry登录密码 +``` + +- 然后在我的仓库管理地址有教我如何推送和拉取镜像: +- 拉取:`docker pull registry.cn-shenzhen.aliyuncs.com/youmeek/redis-to-cluster:[镜像版本号]` +- 推送: + +``` +docker login + +docker tag [ImageId] registry.cn-shenzhen.aliyuncs.com/youmeek/redis-to-cluster:[镜像版本号] + +docker push registry.cn-shenzhen.aliyuncs.com/youmeek/redis-to-cluster:[镜像版本号] +``` + +# Docker 命令,最终部署 Spring Boot 项目 + +- 建议:初期使用的时候尽量用容器 ID / 镜像 ID。如果使用 Tag/Name 在东西多的情况下很容易混乱 还不如就用记不住但是肯定唯一的容器 ID / 镜像 ID + +## 重要的基本概念 + +- 可以代表一个完整的镜像名有两种方式: + - REPOSITORY(仓库):TAG(标签) + - 其中 TAG 表面上不是必须有的,本质是 docker 帮你用 latest 来代替了。latest 这里最好翻译为默认,而不是最新。 + - IMAGE ID(镜像ID) + - 这是一个 Docker 随机给你生成 数字+字母 的字符串 + +## 部署一个 Spring Boot 的 Java Web 项目为例 + +- 宿主机环境说明: + - IP 地址:`http://192.168.137.128` + - 停止了防火墙:`systemctl stop firewalld.service ; systemctl stop iptables.service` + - 停止防火墙后重启 Docker 服务:`systemctl restart docker.service` + - JDK(jdk-8u121-linux-x64.tar.gz)、jar 应用(spring-boot-my-demo.jar),存放宿主机位置:`/opt/setups` + - Spring Boot 的 jar 应用中配置文件给的端口是:8080,常规情况下的访问路径:`http://127.0.0.1:8080/youmeek` +- 下载镜像:`docker pull centos:6.8`,我的 IMAGE_ID 为:`0cd976dc0a98` +- 运行镜像,实例化为一个容器:`docker run -i -t -v /opt/setups:/opt 0cd976dc0a98 /bin/bash` + - `-v:表示需要将本地宿主机的目录挂载到容器中对应的一个目录上,格式:-v <宿主机目录>:<容器目录>,所以此时对容器此目录的操作,也是等同于对宿主机的目录的操作` +- 在容器里安装 Oracle JDK 8、配置 JDK 环境变量这里不多说,具体看:[JDK 安装](https://github.com/judasn/Linux-Tutorial/blob/master/JDK-Install.md)。 +- 把容器中 /opt 目录下的 spring-boot-my-demo.jar 拷贝到容器的 root 目录下:`cp /opt/spring-boot-my-demo.jar /root` +- 再容器里新建脚本:`vi /root/spring-boot-run.sh`,脚本内容如下: + +``` bash +#!/bin/bash +source /etc/profile +java -jar /root/spring-boot-my-demo.jar +``` + +- 在容器中对新建脚本增加执行权限:`chmod u+x /root/spring-boot-run.sh` +- 我们启动另外一个终端 +- 查看我们刚刚运行的容器相关信息:`docker ps -a` + - 我们看到了我们刚刚运行的容器 ID(CONTAINER ID)为:`a5d544d9b6f9`,这个下面要用到 +- 基于刚刚运行的容器创建新镜像:`docker commit a5d544d9b6f9 youmeek/springboot:0.1` + - 查看现在的镜像库:`docker images`,会发现多了一个 youmeek/springboot 新镜像,镜像 ID 为:`7024f230fef9` +- 运行新镜像,实例化为一个容器,并启动容器中刚刚写的脚本:`docker run -d -p 38080:8080 --name=springBootJar --hostname=springBootJar 7024f230fef9 /root/spring-boot-run.sh` + - `-d`:表示以“守护模式”执行 spring-boot-run.sh 脚本,此时 jar 中的 log 日志不会出现在输出终端上。 + - `-p`:表示宿主机与容器的端口映射,此时将容器内部的 8080 端口映射为宿主机的 38080 端口,这样就向外界暴露了 38080 端口,可通过 Docker 网桥来访问容器内部的 8080 端口了。 + - `--name`:表示给新实例容器取的名称,用一个有意义的名称命名即可 +- 查看其实运行的容器:`docker ps -a`,可以知道我们的新容器 ID:`fd21ac056343`,名称为:`springBootJar` +- 查看这个容器的 jar 应用的 log 输出:`docker logs -f fd21ac056343`,可以看到 jar 启动后的 log 输出内容 +- 通过浏览器访问容器中的应用:`http://192.168.137.128:38080/youmeek/`,可以看到 jar 应用的首页可以访问 + +## Docker 基本命令 + +- 官网文档: + + +#### 版本信息 + +- `docker version`,查看docker版本 +- `docker info`,显示docker系统的信息 + +#### 镜像仓库 + +- `docker pull`:从仓库下载镜像到本地 + - `docker pull centos:latest`:获取 CentOS 默认版本镜像 + - `docker pull centos:7.3.1611`:获取 CentOS 7 镜像,下载大小 70M 左右,下面的操作基于此镜像 + - `docker pull centos:6.8`:获取 CentOS 6 镜像 + - `docker pull registry.cn-hangzhou.aliyuncs.com/chainone/centos7-jdk8`:获取别人做好的阿里云镜像 +- `docker push`:将一个镜像 push 到 registry 仓库中 + - `docker push myapache:v1` +- `docker search`:从 registry 仓库搜索镜像 + - `docker search -s 3 centos`,参数 `-s 数字`:表示筛选出收藏数(stars值)大于等于 3 的镜像 +- `docker login`:登录到一个镜像仓库。默认登录的是官网的仓库: + - 登录阿里云仓库格式:`sudo docker login --username=阿里云邮箱` + - 比如我是这个:`docker login --username=23333212@qq.com registry.cn-shenzhen.aliyuncs.com`,你完整的登录地址你需要访问:,在你自己创建的仓库中去查看那份详细操作指南上的地址 + - 密码就是你首次访问:,弹窗出来让你设置的那个密码,如果忘记了重新设置下即可,重设地址:,右上角有一个:修改docker登录密码。 + +#### 本地镜像管理 + +- `docker stats`:查看当前启动的容器各自占用的系统资源 + - `bin docker stats --no-stream kafkadocker_kafka_1 kafkadocker_zookeeper_1`:查看指定容器的占用资源情况 + - 更加高级的监控方式有一个软件叫做:ctop(推荐使用): + +``` +CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS +4532a9ee27b8 cloud-cadvisor 1.49% 53.28MiB / 3.702GiB 1.41% 13.5MB / 646MB 265MB / 0B 19 +3895d5d50a5e kafkadocker_kafka_1 1.45% 1.24GiB / 3.702GiB 33.51% 145MB / 186MB 499MB / 724MB 128 +1d1a6a7c48d8 kafkadocker_zookeeper_1 0.11% 70.85MiB / 3.702GiB 1.87% 55.8MB / 33.7MB 209MB / 1.22MB 23 +``` + +- `docker images`:显示本地所有的镜像列表 + - 关注 REPOSITORY(名称),TAG(标签),IMAGE ID(镜像ID)三列 +- `docker images centos`:查看具体镜像情况 +- `docker rmi`:删除镜像,一般删除镜像前要先删除容器,不然如果镜像有被容器调用会报错 + - `docker rmi 容器ID`:删除具体某一个镜像 + - `docker rmi 仓库:Tag`:删除具体某一个镜像 + - `docker rmi $(docker images -q)`,删除所有镜像 + - `docker rmi -f $(docker images -q)`,强制删除所有镜像 + - `docker rmi $(docker images | grep "vmware" | awk '{print $3}')`,批量删除带有 vmware 名称的镜像 +- `docker tag`:为镜像打上标签 + - `docker tag -f ubuntu:14.04 ubuntu:latest`,-f 意思是强制覆盖 + - 同一个IMAGE ID可能会有多个TAG(可能还在不同的仓库),首先你要根据这些 image names 来删除标签,当删除最后一个tag的时候就会自动删除镜像; + - `docker rmi 仓库:Tag`,取消标签(如果是镜像的最后一个标签,则会删除这个镜像) +- `docker build`:使用 Dockerfile 创建镜像(推荐) + - `docker build . --rm -t runoob/ubuntu:v1`,参数 `-t`,表示:-tag,打标签 + - 多次 docker build 过程中是有依赖一个缓存的过程的,一般 build 过程都有好几个 step,Docker 非常聪明,会自己判断那些没有被修改过程的 step 采用缓存。如果想要避免使用缓存,可以使用这样命令 **--no-cache**:`docker build --no-cache . --rm -t runoob/ubuntu:v1` +- `docker history`:显示生成一个镜像的历史命令,可以看出这个镜像的构建过程,包括:每一层镜像的 ID、指令 +- `docker save`:将一个镜像保存为一个 tar 包,带 layers 和 tag 信息(导出一个镜像) + - `docker save 镜像ID -o /opt/test.tar` +- `docker load`:从一个 tar 包创建一个镜像(导入一个镜像) + - `docker load -i /opt/test.tar` + + +#### 容器生命周期管理 + +- `docker run`,运行镜像 + - `docker run -v /java_logs/:/opt/ -d -p 8080:80 --name=myDockerNameIsGitNavi --hostname=myDockerNameIsGitNavi -i -t 镜像ID /bin/bash` + - `-i -t` 分别表示保证容器中的 STDIN 开启,并分配一个伪 tty 终端进行交互,这两个是合着用。 + - `--name` 是给容器起了一个名字(如果没有主动给名字,docker 会自动给你生成一个)容器的名称规则:大小写字母、数字、下划线、圆点、中横线,用正则表达式来表达就是:[a-zA-Z0-9_*-] + - `-d` 容器运行在后台。 + - `-p 8080:80` 表示端口映射,将宿主机的8080端口转发到容器内的80端口。(如果是 -P 参数,则表示随机映射应该端口,一般用在测试的时候) + - `-v /java_logs/:/opt/` 表示目录挂载,/java_logs/ 是宿主机的目录,/opt/ 是容器目录 + - `docker run --rm --name=myDockerNameIsGitNavi --hostname=myDockerNameIsGitNavi -i -t centos /bin/bash`,--rm,表示退出即删除容器,一般用在做实验测试的时候 + - `docker run --restart=always -i -t centos /bin/bash`,--restart=always 表示停止后会自动重启 + - `docker run --restart=on-failure:5 -i -t centos /bin/bash`,--restart=on-failure:5 表示停止后会自动重启,最多重启 5 次 +- `docker exec`:对守护式的容器里面执行命令,方便对正在运行的容器进行维护、监控、管理 + - `docker exec -i -t 容器ID /bin/bash`,进入正在运行的 docker 容器,并启动终端交互 + - `docker exec -d 容器ID touch /opt/test.txt`,已守护式的方式进入 docker 容器,并创建一个文件 +- `docker stop 容器ID`,停止容器 + - `docker stop $(docker ps -a -q)`,停止所有容器 + - `docker stop $(docker ps -a -q) ; docker rm $(docker ps -a -q)`,停止所有容器,并删除所有容器 + - `docker kill $(docker ps -q) ; docker rm $(docker ps -a -q)`,停止所有容器,并删除所有容器 +- `docker start 容器ID`,重新启动已经停止的容器(重新启动,docker run 参数还是保留之前的) +- `docker restart 容器ID`,重启容器 +- `docker rm`,删除容器 + - `docker rm 容器ID`,删除指定容器(该容器必须是停止的) + - `docker rm -f 容器ID`,删除指定容器(该容器如果正在运行可以这样删除) + - `docker rm $(docker ps -a -q)`,删除所有容器 + - `docker rm -f $(docker ps -a -q)`,强制删除所有容器 + - `docker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm` 删除老的(一周前创建)容器 + - `docker kill $(docker ps -q) ; docker rm $(docker ps -a -q) ; docker rmi $(docker images -q -a)` 停止所有容器,删除所有容器,删除所有镜像 +- `docker commit`,把容器打成镜像 + - `docker commit 容器ID gitnavi/docker-nodejs-test:0.1` + - gitnavi 是你注册的 https://store.docker.com/ 的名字,如果你没有的话,那需要先注册 + - docker-nodejs-test 是你为该镜像起的名字 + - 0.1 是镜像的版本号,默认是 latest 版本 + - `docker commit -m="这是一个描述信息" --author="GitNavi" 容器ID gitnavi/docker-nodejs-test:0.1` + - 在提交镜像时指定更多的数据(包括标签)来详细描述所做的修改 +- `docker diff 容器ID`:显示容器文件系统的前后变化 +- `--link` 同一个宿主机下的不同容器的连接: + - `docker run -it 镜像ID --link redis-name:myredis /bin/bash` + - `redis-name` 是容器名称 + - `myredis` 是容器别名,其他容器连接它可以用这个别名来写入到自己的配置文件中 +- 容器与宿主机之间文件的拷贝 + - `docker cp /www/runoob 96f7f14e99ab:/www/` 将主机 /www/runoob 目录拷贝到容器 96f7f14e99ab 的 /www 目录下 + - `docker cp /www/runoob 96f7f14e99ab:/www` 将主机 /www/runoob 目录拷贝到容器 96f7f14e99ab 中,目录重命名为 www。 + - `docker cp 96f7f14e99ab:/www /tmp/` 将容器96f7f14e99ab的/www目录拷贝到主机的/tmp目录中。 + + +#### docker 网络模式 + +- 查看也有网络:`docker network ls` +- 创建网络:`docker network create --subnet=172.19.0.0/16 net-redis-to-cluster` +- 已有容器连接到某个网络(一个容器可以同时连上多个网络):`docker network connect net-redis-to-cluster my-redis-container` +- 如果是内网提供服务的,可以直接创建一个网络,其服务使用该网络。然后另外一个需要调用该服务的,并且是对外网提供服务的可以使用 host 模式 +- `--network XXXXXX` 常见几种模式 + - bridge 默认模式,在 docker0 的网桥上创建新网络栈,确保独立的网络环境,实现网络隔离:`docker run -it 镜像ID --network=bridge /bin/bash` + - none 不适用网卡,不会有 IP,无法联网:`docker run -it 镜像ID --network=none /bin/bash` + - host 使用宿主机网络 IP、端口联网(在容器里面输入:ip a,看到的结果和在宿主机看到的一样):`docker run -it 镜像ID --network=host /bin/bash` + - 自定义-使用自己命名的网络栈,但是需要手动配置网卡、IP 信息:`docker run -it 镜像ID --network=自定义名称 /bin/bash` + + + +#### 容器管理操作 + +- `docker ps`:列出当前所有 **正在运行** 的容器 + - `docker ps -a`:列出所有的容器(包含历史,即运行过的容器) + - `docker ps -l`:列出最近一次启动的container + - `docker ps -q`:列出最近一次运行的container ID + - `docker ps -a -l`:列出最后一次运行的容器 + - `docker ps -n x`:显示最后 x 个容器,不管是正在运行或是已经停止的 +- `docker top 容器ID`:显示容器的进程信息 +- `docker events`:得到 docker 服务器的实时的事件 +- `docker logs -f 容器ID`:查看容器日志(如果一些容器不断重启,或是自动停止,可以这样看下) + - `docker logs 容器ID`,获取守护式容器的日志 + - `docker logs -f 容器ID`,不断监控容器日志,类似 tail -f + - `docker logs -ft 容器ID`,在 -f 的基础上又增加 -t 表示为每条日志加上时间戳,方便调试 + - `docker logs --tail 10 容器ID`,获取日志最后 10 行 + - `docker logs --tail 0 -f 容器ID`,跟踪某个容器的最新日志而不必读取日志文件 + - `docker logs -f -t --since="2018-05-26" --tail=200 容器ID` 根据某个时间读取日志 + - `docker logs -f -t --since="2018-05-26T11:13:40" --tail=200 容器ID` 根据某个时间读取日志 + - `docker logs -f -t --since="2018-05-25T11:13:40" --until "2018-05-26T11:13:40" --tail=200 容器ID` 根据某个时间读取日志 + - `docker logs --since 10m 容器ID` 查看最近 10 分钟的日志 + - `-f` : 表示查看实时日志 + - `-t` : 显示时间戳 + - `-since` : 显示某个开始时间的所有日志 + - `-tail=200` : 查看最后的 200 条日志 +- `docker wait`,阻塞到一个容器,直到容器停止运行 +- `docker export`,将容器整个文件系统导出为一个tar包,不带layers、tag等信息 +- `docker port`,显示容器的端口映射 +- `docker inspect 容器ID`:查看容器的全面信息,用 JSON 格式输出 +- `docker inspect network名称`:查看 network 信息,用 JSON 格式输出,包含使用该网络的容器有哪些 +- `docker system df`:类似于 Linux 上的 df 命令,用于查看 Docker 的磁盘使用情况 + - Images 镜像 + - Containers 容器 + - Local Volumes 数据卷 + +``` +TYPE TOTAL ACTIVE SIZE RECLAIMABLE +Images 6 6 1.049GB 0B (0%) +Containers 7 4 10.25kB 0B (0%) +Local Volumes 13 5 38.49GB 1.365MB (0%) +Build Cache 0B 0B +``` + +``` +获取容器中的 IP:docker inspect -f {{.NetworkSettings.IPAddress}} 容器ID +获取容器中的 IP:docker inspect -f {{.Volumes}} 容器ID +查看容器的挂载情况:docker inspect 容器ID | grep Mounts -A 10 +``` + +- 下面为一个 docker inspect 后的结果示例: + +```json +[ + { + "Id": "e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b", + "Created": "2018-01-18T03:47:16.138180181Z", + "Path": "docker-entrypoint.sh", + "Args": [ + "--auth" + ], + "State": { + "Status": "running", + "Running": true, + "Paused": false, + "Restarting": false, + "OOMKilled": false, + "Dead": false, + "Pid": 19952, + "ExitCode": 0, + "Error": "", + "StartedAt": "2018-01-18T03:47:16.348568927Z", + "FinishedAt": "0001-01-01T00:00:00Z" + }, + "Image": "sha256:42aa46cfbd7a0d1101311defac39872b447b32295b40f9c99104ede5d02e9677", + "ResolvConfPath": "/var/lib/docker/containers/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b/resolv.conf", + "HostnamePath": "/var/lib/docker/containers/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b/hostname", + "HostsPath": "/var/lib/docker/containers/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b/hosts", + "LogPath": "/var/lib/docker/containers/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b-json.log", + "Name": "/cas-mongo", + "RestartCount": 0, + "Driver": "overlay", + "Platform": "linux", + "MountLabel": "", + "ProcessLabel": "", + "AppArmorProfile": "", + "ExecIDs": null, + "HostConfig": { + "Binds": [ + "/data/mongo/db:/data/db" + ], + "ContainerIDFile": "", + "LogConfig": { + "Type": "json-file", + "Config": {} + }, + "NetworkMode": "default", + "PortBindings": { + "27017/tcp": [ + { + "HostIp": "", + "HostPort": "27017" + } + ] + }, + "RestartPolicy": { + "Name": "always", + "MaximumRetryCount": 0 + }, + "AutoRemove": false, + "VolumeDriver": "", + "VolumesFrom": null, + "CapAdd": null, + "CapDrop": null, + "Dns": [], + "DnsOptions": [], + "DnsSearch": [], + "ExtraHosts": null, + "GroupAdd": null, + "IpcMode": "shareable", + "Cgroup": "", + "Links": null, + "OomScoreAdj": 0, + "PidMode": "", + "Privileged": false, + "PublishAllPorts": false, + "ReadonlyRootfs": false, + "SecurityOpt": null, + "UTSMode": "", + "UsernsMode": "", + "ShmSize": 67108864, + "Runtime": "runc", + "ConsoleSize": [ + 0, + 0 + ], + "Isolation": "", + "CpuShares": 0, + "Memory": 0, + "NanoCpus": 0, + "CgroupParent": "", + "BlkioWeight": 0, + "BlkioWeightDevice": [], + "BlkioDeviceReadBps": null, + "BlkioDeviceWriteBps": null, + "BlkioDeviceReadIOps": null, + "BlkioDeviceWriteIOps": null, + "CpuPeriod": 0, + "CpuQuota": 0, + "CpuRealtimePeriod": 0, + "CpuRealtimeRuntime": 0, + "CpusetCpus": "", + "CpusetMems": "", + "Devices": [], + "DeviceCgroupRules": null, + "DiskQuota": 0, + "KernelMemory": 0, + "MemoryReservation": 0, + "MemorySwap": 0, + "MemorySwappiness": null, + "OomKillDisable": false, + "PidsLimit": 0, + "Ulimits": null, + "CpuCount": 0, + "CpuPercent": 0, + "IOMaximumIOps": 0, + "IOMaximumBandwidth": 0 + }, + "GraphDriver": { + "Data": { + "LowerDir": "/var/lib/docker/overlay/0ab08b1f9c8f5f70cdcac2b01d9ee31de9e5a4955003567573635e8837931249/root", + "MergedDir": "/var/lib/docker/overlay/4d6bb0d57f3f1b1dcf98c70b4bee4abf8dc110c7efa685ee5d84fe6f58c07b63/merged", + "UpperDir": "/var/lib/docker/overlay/4d6bb0d57f3f1b1dcf98c70b4bee4abf8dc110c7efa685ee5d84fe6f58c07b63/upper", + "WorkDir": "/var/lib/docker/overlay/4d6bb0d57f3f1b1dcf98c70b4bee4abf8dc110c7efa685ee5d84fe6f58c07b63/work" + }, + "Name": "overlay" + }, + "Mounts": [ + { + "Type": "volume", + "Name": "6cd9721ff6a2768cd20e4a0678b176fa81a5de1c7d21fe6212b50c6854196db2", + "Source": "/var/lib/docker/volumes/6cd9721ff6a2768cd20e4a0678b176fa81a5de1c7d21fe6212b50c6854196db2/_data", + "Destination": "/data/configdb", + "Driver": "local", + "Mode": "", + "RW": true, + "Propagation": "" + }, + { + "Type": "bind", + "Source": "/data/mongo/db", + "Destination": "/data/db", + "Mode": "", + "RW": true, + "Propagation": "rprivate" + } + ], + "Config": { + "Hostname": "e1dff77b99d9", + "Domainname": "", + "User": "", + "AttachStdin": false, + "AttachStdout": false, + "AttachStderr": false, + "ExposedPorts": { + "27017/tcp": {} + }, + "Tty": false, + "OpenStdin": false, + "StdinOnce": false, + "Env": [ + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + "GOSU_VERSION=1.7", + "GPG_KEYS=0C49F3730359A14518585931BC711F9BA15703C6", + "MONGO_PACKAGE=mongodb-org", + "MONGO_REPO=repo.mongodb.org", + "MONGO_MAJOR=3.4", + "MONGO_VERSION=3.4.10" + ], + "Cmd": [ + "--auth" + ], + "Image": "mongo:3.4", + "Volumes": { + "/data/configdb": {}, + "/data/db": {} + }, + "WorkingDir": "", + "Entrypoint": [ + "docker-entrypoint.sh" + ], + "OnBuild": null, + "Labels": {} + }, + "NetworkSettings": { + "Bridge": "", + "SandboxID": "7eabf418238f4d9f5fd5163fd4d173bbaea7764687a5cf40a9757d42b90ab2f9", + "HairpinMode": false, + "Link LocalIPv6Address": "", + "LinkLocalIPv6PrefixLen": 0, + "Ports": { + "27017/tcp": [ + { + "HostIp": "0.0.0.0", + "HostPort": "27017" + } + ] + }, + "SandboxKey": "/var/run/docker/netns/7eabf418238f", + "SecondaryIPAddresses": null, + "SecondaryIPv6Addresses": null, + "EndpointID": "11c8d10a4be63b4ed710add6c440adf9d090b71918d4aaa837c46258e5425b80", + "Gateway": "172.17.0.1", + "GlobalIPv6Address": "", + "GlobalIPv6PrefixLen": 0, + "IPAddress": "172.17.0.2", + "IPPrefixLen": 16, + "IPv6Gateway": "", + "MacAddress": "02:42:ac:11:00:02", + "Networks": { + "bridge": { + "IPAMConfig": null, + "Links": null, + "Aliases": null, + "NetworkID": "ada97659acda146fc57e15a099e430a6e97de87f6d043b91d4c3582f6ab52d47", + "EndpointID": "11c8d10a4be63b4ed710add6c440adf9d090b71918d4aaa837c46258e5425b80", + "Gateway": "172.17.0.1", + "IPAddress": "172.17.0.2", + "IPPrefixLen": 16, + "IPv6Gateway": "", + "GlobalIPv6Address": "", + "GlobalIPv6PrefixLen": 0, + "MacAddress": "02:42:ac:11:00:02", + "DriverOpts": null + } + } + } + } +] +``` + +## Docker 容器产生的 log 位置 + +- Docker 运行一段时间,如果你的容器有大量的输出信息,则这个 log 文件会非常大,所以要考虑清理。 +- log 位置:`/var/lib/docker/containers/容器ID值/容器ID值-json.log` +- 可以考虑在停到容器的时候备份这个文件到其他位置,然后:`echo > 容器ID值-json.log` +- 当然,官网也提供了自动化的方案: + - 修改 Docker 是配置文件:`vim /etc/docker/daemon.json`,(如果没有这个文件,自己新增)增加如下内容: + +``` bash +{ + "log-driver": "json-file", + "log-opts": { + "max-size": "10m", + "max-file": "5" + } +} +``` + +- 如果你已经有该文件文件莱使用国内源,那修改方案应该是这样的: + +``` bash +{ + "registry-mirrors": ["https://ldhc17y9.mirror.aliyuncs.com"], + "log-driver": "json-file", + "log-opts": { + "max-size": "10m", + "max-file": "5" + } +} +``` + +## 删除 Docker 镜像中为 none 的镜像 + +- Dockerfile 代码更新频繁,自然 docker build 构建同名镜像也频繁的很,产生了众多名为 none 的无用镜像 + + +``` +docker rmi $(docker images -f "dangling=true" -q) +``` + +## Docker daemon.json 可配置参数 + +- + + +## Docker remote api 远程操作配置(保证在内网环境) + +- 假设要被远程操作的服务器 IP:`192.168.1.22` +- 修改其配置文件:`vim /lib/systemd/system/docker.service` +- 修改默认值为:`ExecStart=/usr/bin/dockerd` +- 改为:`ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376` + - 如果还需要连自己的 harbor 这类,完整配置:`ExecStart=/usr/bin/dockerd --insecure-registry harbor.youmeek.com -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376` +- `systemctl daemon-reload` +- `systemctl reload docker` +- `systemctl restart docker` +- 验证: + - 在其他服务器上运行:`docker -H 192.168.1.22:2376 images ` + - 能拿到和它本身看到的一样的数据表示可以了 + + +## Dockerfile 解释 + +- 该文件名就叫 Dockerfile,注意大小写,没有后缀,否则会报错。 +- 主要由下面几个部分组成: + - 基础镜像信息 + - 维护者/创建者信息 + - 镜像操作指令 + - 容器启动时执行执行 +- 注释符号:`# 这是一段注释说明` +- 常用指令关键字: + - `FROM`,基础镜像信息 + - `MAINTAINER`,维护者/创建者信息 + - `ADD`,添加文件。如果添加的文件是类似 tar.gz 压缩包,会自动解压。 + - 特别注意的是:ADD 文件到镜像的地址如果是目录,则需要最后保留斜杠,比如:`ADD test.tar.gz /opt/shell/`。不是斜杠结尾会认为是文件。 + - 添加文件格式:`ADD test.sh /opt/shell/test.sh` + - 添加压缩包并解压格式:`ADD test.tar.gz /opt/shell/`,该压缩包会自动解压在 /opt/shell 目录下 + - `COPY`,类似 ADD,只是 COPY 只是复制文件,不会做类似解压压缩包这种行为。 + - `COPY /opt/conf/ /etc/` 把宿主机的 /opt/conf 下文件复制到镜像的 /etc 目录下。 + - `WORKDIR`,设置工作目录,可以理解为类似 cd 命令,表示现在在某个目录路径,然后下面的 CMD、ENTRYPOINT 操作都是基于此目录 + - `VOLUME`,目录挂载 + - `EXPOSE`,暴露端口 + - `USER`,指定该镜像以什么用户去运行,也可以用这个来指定:`docker run -u root`。不指定默认是 root + - `ENV`,定义环境变量,该变量可以在后续的任何 RUN 指令中使用,使用方式:$HOME_DIR。在 docker run 的时候可以该方式来覆盖变量值 `docker run -e “HOME_DIR=/opt”` + - `RUN`,执行命令并创建新的镜像层,RUN 经常用于安装软件包 + - `CMD`,执行命令,并且一个 Dockerfile 只能有一条 CMD,有多条的情况下最后一条有效。在一种场景下 CMD 命令无效:docker run 的时候也指定了相同命令,则 docker run 命令优先级最高 + - `ENTRYPOINT`,配置容器启动时运行的命令,不会被 docker run 指令覆盖,并且 docker run 的指令可以作为参数传递到 ENTRYPOINT 中。要覆盖 ENTRYPOINT 命令也是有办法的:docker run --entrypoint 方式。Dockerfile 同时有 CMD 和 ENTRYPOINT 的时候,CMD 的指令是作为参数传递给 ENTRYPOINT 使用。 + - 特别注意:RUN、CMD 和 ENTRYPOINT 这三个 Dockerfile 指令看上去很类似,很容易混淆。 + - 最佳实战:[来源](https://www.ibm.com/developerworks/community/blogs/132cfa78-44b0-4376-85d0-d3096cd30d3f/entry/RUN_vs_CMD_vs_ENTRYPOINT_%E6%AF%8F%E5%A4%A95%E5%88%86%E9%92%9F%E7%8E%A9%E8%BD%AC_Docker_%E5%AE%B9%E5%99%A8%E6%8A%80%E6%9C%AF_17?lang=en_us) + - 使用 RUN 指令安装应用和软件包,构建镜像。 + - 如果 Docker 镜像的用途是运行应用程序或服务,比如运行一个 MySQL,应该优先使用 Exec 格式的 ENTRYPOINT 指令。CMD 可为 ENTRYPOINT 提供额外的默认参数,同时可利用 docker run 命令行替换默认参数。 + - 如果想为容器设置默认的启动命令,可使用 CMD 指令。用户可在 docker run 命令行中替换此默认命令。 + + +## Dockerfile 部署 Spring Boot 应用 + +- jar 名称:skb-user-0.0.1-SNAPSHOT.jar +- 打算用的宿主机端口:9096 +- Dockerfile 文件和 jar 文件存放在宿主机目录:/opt/zch +- Dockerfile 内容如下: + +``` bash +FROM java:8-jre +MAINTAINER gitnavi + +ENV TZ=Asia/Shanghai +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +ADD skb-user-0.0.1-SNAPSHOT.jar /usr/local/skb/user/ + +CMD ["java", "-Xmx500m", "-jar", "/usr/local/skb/user/skb-user-0.0.1-SNAPSHOT.jar", "--spring.profiles.active=test"] + +EXPOSE 9096 +``` + +- 开始构建: + - `cd /opt/zch` + - `docker build . --tag="skb/user:v1.0.1"` + - 因为 build 过程中会有多层镜像 step 过程,所以如果 build 过程中失败,那解决办法的思路是找到 step 失败的上一层,成功的 step 中镜像 ID。然后 docker run 该镜像 ID,手工操作,看报什么错误,然后就比较清晰得了解错误情况了。 + - `docker run -d -p 9096:9096 -v /usr/local/logs/:/opt/ --name=skbUser --hostname=skbUser skb/user:v1.0.1` + - 查看启动后容器列表:`docker ps` + - jar 应用的日志是输出在容器的 /opt 目录下,因为我们上面用了挂载,所在在我们宿主机的 /usr/local/logs 目录下可以看到输出的日志 +- 防火墙开放端口: + - `firewall-cmd --zone=public --add-port=9096/tcp --permanent` + - `firewall-cmd --reload` +- 解释: + +``` +# 是为了解决容器的时区和宿主机不一致问题 +ENV TZ=Asia/Shanghai +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone +``` + +## Dockerfile 部署 Tomcat 应用 + +- 编写 Dockerfile + +``` +FROM tomcat:8.0.46-jre8 +MAINTAINER GitNavi + +ENV JAVA_OPTS="-Xms2g -Xmx2g -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=312M" +ENV CATALINA_HOME /usr/local/tomcat + +ENV TZ=Asia/Shanghai +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN rm -rf /usr/local/tomcat/webapps/* + +ADD qiyeweixin.war /usr/local/tomcat/webapps/ + +EXPOSE 8080 + +CMD ["catalina.sh", "run"] +``` + +- 打包镜像:`docker build -t harbor.gitnavi.com/demo/qiyeweixin:1.2.2 ./` +- 运行:`docker run -d -p 8888:8080 --name=qiyeweixin --hostname=qiyeweixin -v /data/docker/logs/qiyeweixin:/data/logs/qiyeweixin harbor.gitnavi.com/demo/qiyeweixin:1.2.2` +- 带 JVM 参数运行:`docker run -d -p 8888:8080 -e JAVA_OPTS='-Xms7g -Xmx7g -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=512M' --name=qiyeweixin --hostname=qiyeweixin -v /data/docker/logs/qiyeweixin:/data/logs/qiyeweixin harbor.gitnavi.com/demo/qiyeweixin:1.2.2` + - 虽然 Dockerfile 已经有 JVM 参数,并且也是有效的。但是如果 docker run 的时候又带了 JVM 参数,则会以 docker run 的参数为准 +- 测试 JVM 是否有效方法,在代码里面书写,该值要接近 xmx 值: + +``` +long maxMemory = Runtime.getRuntime().maxMemory(); +logger.warn("-------------maxMemory=" + ((double) maxMemory / (1024 * 1024))); +``` + +## Docker Compose + +- Docker Compose 主要用于定义和运行多个 Docker 容器的工具,这样可以快速运行一套分布式系统 + - 容器之间是有依赖关系,比如我一个 Java web 系统依赖 DB 容器、Redis 容器,必须这些依赖容器先运行起来。 +- 一个文件:docker-compose.yml +- 一个命令:`docker-compose up` + - 指定文件:`docker-compose -f zookeeper.yml -p zk_test up -d` +- 官网安装说明: +- 安装方法: + +``` +sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose + +sudo chmod +x /usr/local/bin/docker-compose + +``` + +- 检查是否安装成功:`docker-compose --version`,输出:`docker-compose version 1.18.0, build 8dd22a9` +- 常用命令: + - 运行:`docker-compose up -d` + - 停止运行:`docker-compose down` + - 查看容器:`docker-compose ps` + - 删除停止的服务容器:`docker-compose rm` + +## Docker Swarm + +- Docker Swarm 是一个 Docker 集群管理工具 + + +## Harbor 镜像私有仓库 + +- 官网: + +## 资料 + +- 书籍:《第一本 Docker 书》 +- []() +- []() +- []() +- []() +- []() +- []() + + + + + + + + + + + + + + + + + + + + + diff --git a/Dubbo-Install-And-Settings.md b/markdown-file/Dubbo-Install-And-Settings.md similarity index 100% rename from Dubbo-Install-And-Settings.md rename to markdown-file/Dubbo-Install-And-Settings.md diff --git a/markdown-file/ELK-Install-And-Settings.md b/markdown-file/ELK-Install-And-Settings.md new file mode 100644 index 00000000..26fbda70 --- /dev/null +++ b/markdown-file/ELK-Install-And-Settings.md @@ -0,0 +1,38 @@ +# ELK(Elasticsearch、Logstash、Kibana)安装和配置 + +## 版本说明 + +- 本文包含了:Elasticsearch 2.4.X 和 Elasticsearch 5.2.X 和 Elasticsearch 5.5.X,请有针对性地选择。 + +## 教程说明 + + +- 官网: +- 官网总文档: +- 官网最终指南: +- 官网对各个系统的支持列表: +- 5.2 版本有一个设置的新特性必须了解,测试建议我们用 CentOS 7: +- Elasticsearch 开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful 风格接口,多数据源,自动搜索负载等。 +- Logstash 日志进行收集、分析,并将其存储供以后使用(如,搜索) +- kibana 为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助您汇总、分析和搜索重要数据日志。 + + +### Elasticsearch 部署 + +- 请看 Elasticsearch 专题文:[Elasticsearch 相关知识](Elasticsearch-Base.md) + + +### logstash + +- 请看 logstash 专题文:[logstash 相关知识](Logstash-Base.md) + + + +## 资料 + +- +- +- +- +- <> +- <> diff --git a/Elasticsearch-Base.md b/markdown-file/Elasticsearch-Base.md similarity index 70% rename from Elasticsearch-Base.md rename to markdown-file/Elasticsearch-Base.md index c842e03f..959a7a93 100644 --- a/Elasticsearch-Base.md +++ b/markdown-file/Elasticsearch-Base.md @@ -1,18 +1,119 @@ # Elasticsearch 知识 -## 环境 +## Docker 单节点部署 -- CentOS 7.3 +- 官网: +- 官网列表: +- 阿里云支持版本: + - 阿里云有一个 `插件配置` 功能,常用的 Elasticsearch 插件都带了,勾选下即可安装。也支持上传安装。 +- 注意:docker 版本下 client.transport.sniff = true 是无效的。 + +#### 5.6.x + +- `vim ~/elasticsearch-5.6.8-docker.yml` +- 启动:`docker-compose -f ~/elasticsearch-5.6.8-docker.yml -p elasticsearch_5.6.8 up -d` + +``` +version: '3' +services: + elasticsearch1: + image: docker.elastic.co/elasticsearch/elasticsearch:5.6.8 + container_name: elasticsearch-5.6.8 + environment: + - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + - "cluster.name=elasticsearch" + - "network.host=0.0.0.0" + - "http.host=0.0.0.0" + - "xpack.security.enabled=false" + ulimits: + memlock: + soft: -1 + hard: -1 + nofile: + soft: 65536 + hard: 65536 + ports: + - 9200:9200 + - 9300:9300 + volumes: + - /data/docker/elasticsearch/data:/usr/share/elasticsearch/data + +``` + + +#### 6.7.x(带 ik 分词) + +- `vim ~/elasticsearch-6.7.2-docker.yml` +- 启动:`docker-compose -f ~/elasticsearch-6.7.2-docker.yml -p elasticsearch_6.7.2 up -d` +- `mkdir -p /data/docker/elasticsearch-6.7.2/data` +- 如果官网镜像比较慢可以换成阿里云:`registry.cn-hangzhou.aliyuncs.com/elasticsearch/elasticsearch:6.7.2` +- 下载 ik 分词(版本必须和 Elasticsearch 版本对应,包括小版本号): + +``` +version: '3' +services: + elasticsearch1: + image: docker.elastic.co/elasticsearch/elasticsearch:6.7.2 + container_name: elasticsearch-6.7.2 + environment: + - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + - "cluster.name=elasticsearch" + - "network.host=0.0.0.0" + - "http.host=0.0.0.0" + - "xpack.security.enabled=false" + ulimits: + memlock: + soft: -1 + hard: -1 + nofile: + soft: 65536 + hard: 65536 + ports: + - 9200:9200 + - 9300:9300 + volumes: + - /data/docker/elasticsearch-6.7.2/data:/usr/share/elasticsearch/data + - /data/docker/ik:/usr/share/elasticsearch/plugins/ik +``` + +- Elasticsearch Head 插件地址: +- 测试: + + +``` +http://localhost:9200/ +_analyze?pretty POST + + +{"analyzer":"ik_smart","text":"安徽省长江流域"} +``` + +- ik_max_word 和 ik_smart 什么区别? + +``` +ik_max_word: 会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合,适合 Term Query; +ik_smart: 会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”,适合 Phrase 查询。 +``` + + +------------------------------------------------------------------- + + +## Elasticsearch 6.5.x 安装(适配与 5.5.x,6.6.x) + +#### 环境 + +- CentOS 7.x +- 至少需要 2G 内存 - root 用户 - JDK 版本:1.8(最低要求),主推:JDK 1.8.0_121 以上 - 关闭 firewall - `systemctl stop firewalld.service` #停止firewall - `systemctl disable firewalld.service` #禁止firewall开机启动 -## Elasticsearch 5.5.0 安装 - -### 先配置部分系统变量 +#### 先配置部分系统变量 +- 更多系统层面的配置可以看官网: - 配置系统最大打开文件描述符数:`vim /etc/sysctl.conf` ``` @@ -29,12 +130,27 @@ elasticsearch hard memlock unlimited * hard nofile 262144 ``` -### 开始安装 +#### 开始安装 -- 官网 RPM 安装流程(重要,以下资料都是对官网的总结): -- `rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch` +- 检查:`rpm -qa | grep elastic` +- 卸载:`rpm -e --nodeps elasticsearch` +- 官网 RPM 安装流程(重要,以下资料都是对官网的总结): +- 导入 KEY:`rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch` - 新建文件:`vim /etc/yum.repos.d/elasticsearch.repo` -- 内容如下: +- 内容如下(6.x): + +``` +[elasticsearch-6.x] +name=Elasticsearch repository for 6.x packages +baseurl=https://artifacts.elastic.co/packages/6.x/yum +gpgcheck=1 +gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch +enabled=1 +autorefresh=1 +type=rpm-md +``` + +- 内容如下(5.x): ``` [elasticsearch-5.x] @@ -47,24 +163,135 @@ autorefresh=1 type=rpm-md ``` -- 开始安装:`yum install -y elasticsearch`,国内网络安装会很慢,慢慢等 +- 开始安装:`yum install -y elasticsearch`,预计文件有 108M 左右,国内网络安装可能会很慢,慢慢等 + - 安装完后会多了一个:elasticsearch 用户和组 +- 设置 java 软链接:`ln -s /usr/local/jdk1.8.0_181/jre/bin/java /usr/local/sbin/java` +- 启动和停止软件(默认是不启动的): + - 启动:`systemctl start elasticsearch.service` + - 状态:`systemctl status elasticsearch.service` + - 停止:`systemctl stop elasticsearch.service` + - 重新启动:`systemctl restart elasticsearch.service` - 安装完成后,增加系统自启动: -- `/bin/systemctl daemon-reload` -- `/bin/systemctl enable elasticsearch.service` -- 启动和停止软件: -- `systemctl start elasticsearch.service` -- `systemctl stop elasticsearch.service` + - `/bin/systemctl daemon-reload` + - `/bin/systemctl enable elasticsearch.service` +- 检查:`curl -X GET "localhost:9200/"` -### RPM 安装后的一些配置位置说明 +#### RPM 安装后的一些配置位置说明 +- 更多说明可以看官网: +- 更加详细的配置可以看: - 默认系统生成了一个 elasticsearch 用户,下面的目录权限属于该用户 -- Elasticsearch 安装后位置:/usr/share/elasticsearch -- Elasticsearch 的软件环境、堆栈的设置:/etc/sysconfig/elasticsearch -- Elasticsearch 的集群设置:/etc/elasticsearch/elasticsearch.yml -- Log 位置:/var/log/elasticsearch/ -- 索引数据位置:/var/lib/elasticsearch -- 插件位置:/usr/share/elasticsearch/plugins -- 脚本文件位置:/etc/elasticsearch/scripts +- Elasticsearch 安装后位置:`/usr/share/elasticsearch` +- Elasticsearch 的软件环境、堆栈的设置:`/etc/sysconfig/elasticsearch` +- Elasticsearch 的集群设置:`/etc/elasticsearch/elasticsearch.yml` +- Log 位置:`/var/log/elasticsearch/` +- 索引数据位置:`/var/lib/elasticsearch` +- 插件位置:`/usr/share/elasticsearch/plugins` +- 脚本文件位置:`/etc/elasticsearch/scripts` + +#### 配置 + +- 编辑配置文件:`vim /etc/elasticsearch/elasticsearch.yml` +- 默认只能 localhost 访问,修改成支持外网访问 + +``` +打开这个注释:#cluster.name: my-application +集群名称最好是自己给定,不然有些 client 端会连不上,或者要求填写 + +打开这个注释:#network.host: 192.168.0.1 +改为:network.host: 0.0.0.0 +``` + +#### 安装 X-Pack(6.5.x 默认带了 x-pack) + +- `cd /usr/share/elasticsearch && bin/elasticsearch-plugin install x-pack` + +#### GUI 客户端工具 + +- 优先推荐: +- + + +#### 安装 Chrome 扩展的 Head + +- 下载地址: + +#### 其他细节 + +- 如果就单个节点测试,新建索引的时候副本数记得填 0。 + +#### 创建索引并设置 mapping + +- 官网类型说明: + +``` +curl -XPUT 'http://127.0.0.1:9200/grafanadb' -H 'Content-Type: application/json' -d' +{ + "settings": { + "refresh_interval": "5s", + "number_of_shards": 5, + "number_of_replicas": 0 + }, + "mappings": { + "radar": { + "properties": { + "request_num": { + "type": "long" + }, + "post_date": { + "type": "date", + "format": "yyyy-MM-dd HH:mm:ss||epoch_millis" + } + } + } + } +} +' +``` + + +#### 批量增加 / 删除测试数据 + +- 官网文档: +- 批量增加,cURL 格式: + +``` +curl -X POST "http://127.0.0.1:9200/_bulk" -H 'Content-Type: application/json' -d' +{ "index" : { "_index" : "grafanadb", "_type" : "radar", "_id" : "100001" } } +{ "post_date" : "2018-12-01 10:00:00", "request_num" : 1 } +{ "index" : { "_index" : "grafanadb", "_type" : "radar", "_id" : "100002" } } +{ "post_date" : "2018-12-01 10:00:05", "request_num" : 2 } +{ "index" : { "_index" : "grafanadb", "_type" : "radar", "_id" : "100003" } } +{ "post_date" : "2018-12-01 10:00:10", "request_num" : 3 } +{ "index" : { "_index" : "grafanadb", "_type" : "radar", "_id" : "100004" } } +{ "post_date" : "2018-12-01 10:00:15", "request_num" : 4 } +{ "index" : { "_index" : "grafanadb", "_type" : "radar", "_id" : "100005" } } +{ "post_date" : "2018-12-01 10:00:20", "request_num" : 5 } +' +``` + +- 批量删除,cURL 格式: + +``` +curl -X POST "http://127.0.0.1:9200/_bulk" -H 'Content-Type: application/json' -d' +{ "delete": { "_index": "grafanadb", "_type": "radar", "_id": "100001" } } +{ "delete": { "_index": "grafanadb", "_type": "radar", "_id": "100002" } } +' +``` + +- 清空索引所有数据,分成5个切片去执行删除,cURL 格式: + +``` +curl -X POST "http://127.0.0.1:9200/索引名称/类型名称/_delete_by_query?refresh&slices=5&pretty" -H 'Content-Type: application/json' -d' +{ + "query": { + "match_all": {} + } +} +' +``` + + ------------------------------------------------------------------------------------------------------------------- diff --git a/FTP.md b/markdown-file/FTP.md similarity index 99% rename from FTP.md rename to markdown-file/FTP.md index 51dc097a..53fb9149 100644 --- a/FTP.md +++ b/markdown-file/FTP.md @@ -52,7 +52,7 @@ ## vsftpd 的两种传输模式 - 分为:主动模式(PORT)和被动模式(PASV)。这两个模式会涉及到一些端口问题,也就涉及到防火墙问题,所以要特别注意。主动模式比较简单,只要在防火墙上放开放开 21 和 20 端口即可。被动模式则要根据情况放开一个端口段。 - - ![vsftpd 的两种传输模式](images/FTP-a-1.jpg) + - ![vsftpd 的两种传输模式](../images/FTP-a-1.jpg) - 上图箭头:xftp 新建连接默认都是勾选被动模式的,所以如果要使用主动模式,在该连接的属性中是要去掉勾选。 ## vsftpd 的两种运行模式 diff --git a/FastDFS-Install-And-Settings.md b/markdown-file/FastDFS-Install-And-Settings.md similarity index 97% rename from FastDFS-Install-And-Settings.md rename to markdown-file/FastDFS-Install-And-Settings.md index cb6133c5..52412272 100644 --- a/FastDFS-Install-And-Settings.md +++ b/markdown-file/FastDFS-Install-And-Settings.md @@ -1,32 +1,19 @@ # FastDFS 安装和配置 -## 它是什么 +## FastDFS 介绍 - FastDFS 介绍: - 官网下载 1: - 官网下载 2: - 官网下载 3: - -## 为什么会出现 - - - -## 哪些人喜欢它 - - -## 哪些人不喜欢它 - - - -## 为什么学习它 - - - - -## 同类工具 - - +- 主要场景: + - 小图片 + - 音频、小视频 + - 其他类型小文件 +- 更加复杂的文件存储场景可以选择:[Ceph](https://ceph.com/) + - 支持对象存储、块存储和文件存储 + - 高性能、高可靠性和高扩展 ### 单机安装部署(CentOS 6.7 环境) @@ -212,7 +199,7 @@ ``` - 在终端中通过 shell 上传 opt 目录下的一张图片:`/usr/bin/fdfs_test /etc/fdfs/client.conf upload /opt/test.jpg` - 如下图箭头所示,生成的图片地址为:`http://192.168.1.114/group1/M00/00/00/wKgBclb0aqWAbVNrAAAjn7_h9gM813_big.jpg` - - ![FastDFS](images/FastDFS-a-1.jpg) + - ![FastDFS](../images/FastDFS-a-1.jpg) - 即使我们现在知道图片的访问地址我们也访问不了,因为我们还没装 FastDFS 的 Nginx 模块 - 安装 **fastdfs-nginx-module_v1.16.tar.gz**,安装 Nginx 第三方模块相当于这个 Nginx 都是要重新安装一遍的 - 解压 Nginx 模块:`tar zxvf fastdfs-nginx-module_v1.16.tar.gz`,得到目录地址:**/opt/setups/FastDFS/fastdfs-nginx-module** diff --git a/FastDFS-Nginx-Lua-GraphicsMagick.md b/markdown-file/FastDFS-Nginx-Lua-GraphicsMagick.md similarity index 99% rename from FastDFS-Nginx-Lua-GraphicsMagick.md rename to markdown-file/FastDFS-Nginx-Lua-GraphicsMagick.md index 4bca747d..3e051a4f 100644 --- a/FastDFS-Nginx-Lua-GraphicsMagick.md +++ b/markdown-file/FastDFS-Nginx-Lua-GraphicsMagick.md @@ -181,7 +181,7 @@ ``` - 在终端中通过 shell 上传 opt 目录下的一张图片:`/usr/bin/fdfs_test /etc/fdfs/client.conf upload /opt/test.jpg` - 如下图箭头所示,生成的图片地址为:`http://192.168.1.114/group1/M00/00/00/wKgBclb0aqWAbVNrAAAjn7_h9gM813_big.jpg` - - ![FastDFS](images/FastDFS-a-1.jpg) + - ![FastDFS](../images/FastDFS-a-1.jpg) - 即使我们现在知道图片的访问地址我们也访问不了,因为我们还没装 FastDFS 的 Nginx 模块 diff --git a/File-Extract-Compress.md b/markdown-file/File-Extract-Compress.md similarity index 64% rename from File-Extract-Compress.md rename to markdown-file/File-Extract-Compress.md index 7c3b309b..fd03c1dd 100644 --- a/File-Extract-Compress.md +++ b/markdown-file/File-Extract-Compress.md @@ -1,7 +1,7 @@ # Linux 下常用压缩文件的解压、压缩 -## 常用压缩包**解压**命令整理 +## 常用压缩包--解压--令整理 - Linux 后缀为 `.war` 格式的文件(一般用在部署 Tomcat 项目的时候) - 命令:`unzip -oq XXXXXX.war -d ROOT` @@ -37,7 +37,11 @@ ----------------------------------------------------------- -## 常用文件进行**压缩**命令整理 +## 常用文件进行--压缩--命令整理 + +- Linux 压缩文件夹为后缀 `.war` 格式的文件(最好不要对根目录进行压缩,不然会多出一级目录) +- 命令:`jar -cvfM0 cas.war /opt/cas/META-INF /opt/cas/WEB-INF /opt/cas/index.jsp` +- 或者命令:`cd 项目根目录 ; jar -cvfM0 cas.war ./*` - Linux 压缩文件为后缀 `.tar` 格式的文件 - 命令:`tar -zcvf test11.tar test11` @@ -58,6 +62,20 @@ - 命令:`7za a test1.7z /opt/test1/` +## 分卷压缩 + +- 分卷压缩:`zip -s 100M myFile.zip --out newFile.zip` +- 最终效果: + +``` +newFile.z01 +newFile.z02 +newFile.z03 +newFile.z04 +newFile.zip +``` + + ## 特殊格式 - 7z @@ -75,6 +93,20 @@ - 安装:`make install` - rar 解压:`rar x 文件名.rar` +## jar 包操作 + +### 修改 jar 包配置文件 + +- 命令:`vim mytest.jar`,这时候会展示 jar 中所有层级目录下的所有文件 +- 输入:`/log4j2.xml` 回车,光标定位到该文件,然后再回车,进入编辑该文件状态 +- 此时可以修改配置文件了,修改后 `:wq` 保存退出,接着 `:q` 退出 jar 编辑状态 + +### 更新 Jar 包中的文件 + +- 替换(新增)jar 根目录下的文件:`jar uvf mytest.jar ClassToAdd.class` +- 一般 class 文件都是在多层目录里面的,需要这样做:`jar uvf mytest.jar com/youmeek/ClassToAdd.class` + - 需要在 jar 所在的文件夹下创建:`mkdir -p ./com/youmeek`,该目录必须和原 jar 里面的层级目录结构一致 + ## 资料 diff --git a/markdown-file/Flink-Install-And-Settings.md b/markdown-file/Flink-Install-And-Settings.md new file mode 100644 index 00000000..97d813c0 --- /dev/null +++ b/markdown-file/Flink-Install-And-Settings.md @@ -0,0 +1,371 @@ +# Flink 安装和配置 + +## 介绍 + +- 2018-11-30 发布最新:1.7.0 版本 +- 官网: +- 官网 Github: + +## 本地模式安装 + +- CentOS 7.4 +- IP 地址:`192.168.0.105` +- 官网指导: +- 必须 JDK 8.x +- 下载: + - 选择 Binaries 类型 + - 如果没有 Hadoop 环境,只是本地开发,选择:Apache 1.7.0 Flink only + - Scala 2.11 和 Scala 2.12 都可以,但是我因为后面要用到 kafka,kafka 推荐 Scala 2.11,所以我这里也选择同样。 + - 最终我选择了:Apache 1.7.0 Flink only Scala 2.11,共:240M +- 解压:`tar zxf flink-*.tgz` +- 进入根目录:`cd flink-1.7.0`,完整路径:`cd /usr/local/flink-1.7.0` +- 改下目录名方便后面书写:`mv /usr/local/flink-1.7.0 /usr/local/flink` +- 启动:`cd /usr/local/flink && ./bin/start-cluster.sh` +- 停止:`cd /usr/local/flink && ./bin/stop-cluster.sh` +- 查看日志:`tail -300f log/flink-*-standalonesession-*.log` +- 浏览器访问 WEB 管理:`http://192.168.0.105:8081` + +## yarn 启动 + +- 安装方式跟上面一样,但是必须保证有 hadoop、yarn 集群 +- 控制台启动:`cd /usr/local/flink && ./bin/yarn-session.sh -n 2 -jm 1024 -tm 1024` +- 守护进程启动:`cd /usr/local/flink && ./bin/yarn-session.sh -n 2 -jm 1024 -tm 1024 -d` +- 有可能会报:`The Flink Yarn cluster has failed`,可能是资源不够 +- YARN 参数配置可以参考:[点击我](https://sustcoder.github.io/2018/09/27/YARN%20%E5%86%85%E5%AD%98%E5%8F%82%E6%95%B0%E8%AF%A6%E8%A7%A3/) + +## Demo + +- 运行程序解压包下也有一些 jar demo:`cd /usr/local/flink/examples` +- 官网: +- DataStream API: +- DataSet API: +- 访问该脚本可以得到如下内容: + +``` +mvn archetype:generate \ + -DarchetypeGroupId=org.apache.flink \ + -DarchetypeArtifactId=flink-quickstart-java \ + -DarchetypeVersion=${1:-1.7.0} \ + -DgroupId=org.myorg.quickstart \ + -DartifactId=$PACKAGE \ + -Dversion=0.1 \ + -Dpackage=org.myorg.quickstart \ + -DinteractiveMode=false +``` + +- 可以自己在本地执行该 mvn 命令,用 Maven 骨架快速创建一个 WordCount 项目 +- 注意,这里必须使用这个仓库(最好用穿越软件):`https://repository.apache.org/content/repositories/snapshots` +- 该骨架的所有版本: + - 根据实验,目前 1.7.0 和 1.6.x 都是没有 WordCount demo 代码的。但是 1.3.x 是有的。 + +## 运行 + +- 可以直接在 IntelliJ IDEA 上 run +- 也可以交给服务器上 flink 执行,也有两种方式: + - 把 jar 自己上传 Flink 服务器运行:`cd /usr/local/flink && ./bin/flink run -c com.youmeek.WordCount /opt/flink-simple-demo-1.0-SNAPSHOT.jar` + - 也可以通过 WEB UI 上传 jar: + - 有一个 `Add New` 按钮可以上传 jar 包,然后填写 Class 路径:`com.youmeek.WordCount` + - `parallelism` 表示并行度,填写数字,一般并行度设置为集群 CPU 核数总和的 2-3 倍(如果是单机模式不需要设置并行度) + +## 安装 ncat 方便发送数据包 + +- 环境:CentOS 7.4 +- 官网下载:,找到 rpm 包 +- 当前时间(201803)最新版本下载:`wget https://nmap.org/dist/ncat-7.60-1.x86_64.rpm` +- 当前时间(201812)最新版本下载:`wget https://nmap.org/dist/ncat-7.70-1.x86_64.rpm` +- 安装:`sudo rpm -i ncat-7.60-1.x86_64.rpm` +- ln 下:`sudo ln -s /usr/bin/ncat /usr/bin/nc` +- 检验:`nc --version` +- 启动监听 9011 端口:`nc -lk 9011`,然后你可以输入内容,Flink demo 看是否有收到 + +------------------------------------------------------------------- + + +## Flink 核心概念 + +- 四个基石:Checkpoint、State、Time、Window +- 解决 exactly-once 的问题 +- 实现了 watermark 的机制,解决了基于事件时间处理时的数据乱序和数据迟到的问题 +- 状态管理 +- 提供了一套开箱即用的窗口操作,包括滚动窗口、滑动窗口、会话窗口 +- 我想说的,都被这篇文章说了: + - + - +- 这里补充点其他的 + + +``` +Client 用来提交任务给 JobManager,JobManager 分发任务给 TaskManager 去执行,然后 TaskManager 会心跳的汇报任务状态 +在 Flink 集群中,计算资源被定义为 Task Slot +每个 TaskManager 会拥有一个或多个 Slots + +JobManager 会以 Slot 为单位调度 Task。 +对 Flink 的 JobManager 来说,其调度的是一个 Pipeline 的 Task,而不是一个点。 +在 Flink 中其也是一个被整体调度的 Pipeline Task。在 TaskManager 中,根据其所拥有的 Slot 个数,同时会拥有多个 Pipeline + + +Task Slot +在架构概览中我们介绍了 TaskManager 是一个 JVM 进程,并会以独立的线程来执行一个task或多个subtask。为了控制一个 TaskManager 能接受多少个 task,Flink 提出了 Task Slot 的概念。 + +Flink 中的计算资源通过 Task Slot 来定义。每个 task slot 代表了 TaskManager 的一个固定大小的资源子集。例如,一个拥有3个slot的 TaskManager,会将其管理的内存平均分成三分分给各个 slot。将资源 slot 化意味着来自不同job的task不会为了内存而竞争,而是每个task都拥有一定数量的内存储备。需要注意的是,这里不会涉及到CPU的隔离,slot目前仅仅用来隔离task的内存。 +通过调整 task slot 的数量,用户可以定义task之间是如何相互隔离的。每个 TaskManager 有一个slot,也就意味着每个task运行在独立的 JVM 中。每个 TaskManager 有多个slot的话,也就是说多个task运行在同一个JVM中。而在同一个JVM进程中的task,可以共享TCP连接(基于多路复用)和心跳消息,可以减少数据的网络传输。也能共享一些数据结构,一定程度上减少了每个task的消耗。 + +每一个 TaskManager 会拥有一个或多个的 task slot,每个 slot 都能跑由多个连续 task 组成的一个 pipeline,比如 MapFunction 的第n个并行实例和 ReduceFunction 的第n个并行实例可以组成一个 pipeline。 + +source(Streaming 进来) +Transformations(Streaming 处理) +sink(Streaming 出去) + +Flink程序与生俱来的就是并行和分布式的。Streams被分割成stream patition, Operators被被分割成operator subtasks。这些subtasks在不同的机器(容器)上的不同的线程中运行,彼此独立,互不干扰。 一个操作的operator subtask的数目,被称为parallelism(并行度)。一个stream的并行度,总是等于生成它的(operator)操作的并行度。一个Flink程序中,不同的operator可能具有不同的并行度。 +``` + +------------------------------------------------------------------- + + +#### 为了容错的 Checkpoint 机制 + +- 这几篇文章写得很好: + - [Flink 增量式checkpoint 介绍](https://my.oschina.net/u/992559/blog/2873828) + - [A Deep Dive into Rescalable State in Apache Flink](https://flink.apache.org/features/2017/07/04/flink-rescalable-state.html) + - [Flink 小贴士 (5): Savepoint 和 Checkpoint 的 3 个不同点](http://wuchong.me/blog/2018/11/25/flink-tips-differences-between-savepoints-and-checkpoints/) + - [Flink 小贴士 (2):Flink 如何管理 Kafka 消费位点](http://wuchong.me/blog/2018/11/04/how-apache-flink-manages-kafka-consumer-offsets/) +- Checkpoint 允许 Flink 恢复流中的状态和位置,使应用程序具有与无故障执行相同的语义 +- Checkpoint 是 Flink 用来从故障中恢复的机制,快照下了整个应用程序的状态,当然也包括输入源读取到的位点。如果发生故障,Flink 将通过从 Checkpoint 加载应用程序状态并从恢复的读取位点继续应用程序的处理,就像什么事情都没发生一样。 + + +``` +一个checkpoint是Flink的一致性快照,它包括: + +程序当前的状态 +输入流的位置 +Flink通过一个可配置的时间,周期性的生成checkpoint,将它写入到存储中,例如S3或者HDFS。写入到存储的过程是异步的,意味着Flink程序在checkpoint运行的同时还可以处理数据。 + +在机器或者程序遇到错误重启的时候,Flink程序会使用最新的checkpoint进行恢复。Flink会恢复程序的状态,将输入流回滚到checkpoint保存的位置,然后重新开始运行。这意味着Flink可以像没有发生错误一样计算结果。 + +检查点(Checkpoint)是使 Apache Flink 能从故障恢复的一种内部机制。检查点是 Flink 应用状态的一个一致性副本,包括了输入的读取位点。在发生故障时,Flink 通过从检查点加载应用程序状态来恢复,并从恢复的读取位点继续处理,就好像什么事情都没发生一样。你可以把检查点想象成电脑游戏的存档一样。如果你在游戏中发生了什么事情,你可以随时读档重来一次。 +检查点使得 Apache Flink 具有容错能力,并确保了即时发生故障也能保证流应用程序的语义。检查点是以固定的间隔来触发的,该间隔可以在应用中配置。 + +``` + +- 默认情况下 checkpoint 是不启用的,为了启用 checkpoint,需要在 StreamExecutionEnvironment 中调用 enableCheckpointing(n) 方法, 其中 n 是 checkpoint 的间隔毫秒数。 +- 这里有一个核心:用到 Facebook 的 RocksDB 数据库(可嵌入式的支持持久化的 key-value 存储系统) + + +------------------------------------------------------------------- + +#### Exactly-Once + +- 因为有了 Checkpoint,才有了 Exactly-Once +- [Apache Flink 端到端(end-to-end)Exactly-Once特性概览 (翻译)](https://my.oschina.net/u/992559/blog/1819948) +- 常见有这几种语义: + +``` +at most once : 至多一次。可能导致消息丢失。 +at least once : 至少一次。可能导致消息重复。 +exactly once : 刚好一次。不丢失也不重复。 +``` + + +------------------------------------------------------------------- + + +#### Watermark + +- [Flink 小贴士 (3): 轻松理解 Watermark](http://wuchong.me/blog/2018/11/18/flink-tips-watermarks-in-apache-flink-made-easy/) +- 了解事件时间的几个概念:event-time【消息产生的时间】, processing-time【消息处理时间】, ingestion-time【消息流入 flink 框架的时间】 +- watermark 的作用,他们定义了何时不再等待更早的数据 +- WaterMark 只在时间特性 EventTime 和 IngestionTime 起作用,并且 IngestionTime 的时间等同于消息的 ingestion 时间 + +------------------------------------------------------------------- + +#### 窗口 + +- +- [Flink 原理与实现:Window 机制](http://wuchong.me/blog/2016/05/25/flink-internals-window-mechanism/) +- [Flink 原理与实现:Session Window](http://wuchong.me/blog/2016/06/06/flink-internals-session-window/) + +##### 滚动窗口(Tumbling Windows) + +- 滚动窗口有一个固定的大小,并且不会出现重叠 + +###### 滚动事件时间窗口 + +``` +input + .keyBy() + .window(TumblingEventTimeWindows.of(Time.seconds(5))) + .(); +``` + +- 每日偏移8小时的滚动事件时间窗口 + +``` +input + .keyBy() + .window(TumblingEventTimeWindows.of(Time.days(1), Time.hours(-8))) + .(); +``` + +###### 滚动处理时间窗口 + +``` +input + .keyBy() + .window(TumblingProcessingTimeWindows.of(Time.seconds(5))) + .(); +``` + +--------------------------------- + +##### 滑动窗口(Sliding Windows) + +- 滑动窗口分配器将元素分配到固定长度的窗口中,与滚动窗口类似,窗口的大小由窗口大小参数来配置,另一个窗口滑动参数控制滑动窗口开始的频率。因此,滑动窗口如果滑动参数小于滚动参数的话,窗口是可以重叠的,在这种情况下元素会被分配到多个窗口中。 +- 例如,你有10分钟的窗口和5分钟的滑动,那么每个窗口中5分钟的窗口里包含着上个10分钟产生的数据 + +###### 滑动事件时间窗口 + +``` +input + .keyBy() + .window(SlidingEventTimeWindows.of(Time.seconds(10), Time.seconds(5))) + .(); +``` + +###### 滑动处理时间窗口 + +``` +input + .keyBy() + .window(SlidingProcessingTimeWindows.of(Time.seconds(10), Time.seconds(5))) + .(); +``` + +- 偏移8小时的滑动处理时间窗口 + +``` +input + .keyBy() + .window(SlidingProcessingTimeWindows.of(Time.hours(12), Time.hours(1), Time.hours(-8))) + .(); +``` + +--------------------------------- + +##### 计数窗口(Count Window) + +- 根据元素个数对数据流进行分组的 + +###### 翻滚计数窗口 + +- 当我们想要每 100 个用户购买行为事件统计购买总数,那么每当窗口中填满 100 个元素了,就会对窗口进行计算,这种窗口我们称之为翻滚计数窗口(Tumbling Count Window) + +``` +input + .keyBy() + .countWindow(100) + .(); +``` + +--------------------------------- + + +##### 会话窗口(Session Windows) + +- session 窗口分配器通过 session 活动来对元素进行分组,session 窗口跟滚动窗口和滑动窗口相比,不会有重叠和固定的开始时间和结束时间的情况。相反,当它在一个固定的时间周期内不再收到元素,即非活动间隔产生,那个这个窗口就会关闭。一个 session 窗口通过一个 session 间隔来配置,这个 session 间隔定义了非活跃周期的长度。当这个非活跃周期产生,那么当前的 session 将关闭并且后续的元素将被分配到新的 session 窗口中去。 + +###### 事件时间会话窗口 + +``` +input + .keyBy() + .window(EventTimeSessionWindows.withGap(Time.minutes(10))) + .(); +``` + +###### 处理时间会话窗口 + +``` +input + .keyBy() + .window(ProcessingTimeSessionWindows.withGap(Time.minutes(10))) + .(); +``` + +--------------------------------- + +##### 全局窗口(Global Windows) + +- 全局窗口分配器将所有具有相同 key 的元素分配到同一个全局窗口中,这个窗口模式仅适用于用户还需自定义触发器的情况。否则,由于全局窗口没有一个自然的结尾,无法执行元素的聚合,将不会有计算被执行。 + +``` +input + .keyBy() + .window(GlobalWindows.create()) + .(); +``` + +------------------------------------------------------------------- + + +#### 生产环境准备 + +- [Flink 小贴士 (7): 4个步骤,让 Flink 应用达到生产状态](http://wuchong.me/blog/2018/12/03/flink-tips-4-steps-flink-application-production-ready/) + +------------------------------------------------------------------- + + +#### 运行环境 + + +- Flink 的部署 +- Flink 有三种部署模式,分别是 Local、Standalone Cluster 和 Yarn Cluster。 +- 对于 Local 模式来说,JobManager 和 TaskManager 会公用一个 JVM 来完成 Workload。 +- 如果要验证一个简单的应用,Local 模式是最方便的。实际应用中大多使用 Standalone 或者 Yarn Cluster + +------------------------------------------------------------------- + +#### Flink 的 HA + +------------------------------------------------------------------- + +#### Monitoring REST API + +https://ci.apache.org/projects/flink/flink-docs-stable/monitoring/rest_api.html#monitoring-rest-api + +------------------------------------------------------------------- + +#### 主要核心 API + +- 官网 API 文档: +- DataStream API -- Stream Processing +- DataSet API -- Batch Processing +- Kafka source + - Kafka Connectors +- Elasticsearch sink + +------------------------------------------------------------------- + +#### Table & SQL API(关系型 API) + +Table API:为Java&Scala SDK提供类似于LINQ(语言集成查询)模式的API(自0.9.0版本开始) +SQL API:支持标准SQL(自1.1.0版本开始) + + +关系型API作为一个统一的API层,既能够做到在Batch模式的表上进行可终止地查询并生成有限的结果集,同时也能做到在Streaming模式的表上持续地运行并生产结果流,并且在两种模式的表上的查询具有相同的语法跟语义。这其中最重要的概念是Table,Table与DataSet、DataStream紧密结合,DataSet和DataStream都可以很容易地转换成Table,同样转换回来也很方便。 + +关系型API架构在基础的DataStream、DataSet API之上,其整体层次关系如下图所示: + +![table-sql-level](http://7xkaaz.com1.z0.glb.clouddn.com/table-sql-level.png) + +------------------------------------------------------------------- + + +## 资料 + +- [新一代大数据处理引擎 Apache Flink](https://www.ibm.com/developerworks/cn/opensource/os-cn-apache-flink/index.html) +- [Flink-关系型API简介](http://vinoyang.com/2017/07/06/flink-relation-api-introduction/) +- [Flink学习笔记(4):基本概念](https://www.jianshu.com/p/0cd1db4282be) +- [Apache Flink:特性、概念、组件栈、架构及原理分析](http://shiyanjun.cn/archives/1508.html) +- [Flink 原理与实现:理解 Flink 中的计算资源](http://wuchong.me/blog/2016/05/09/flink-internals-understanding-execution-resources/) +- [Flink实战教程](https://liguohua-bigdata.gitbooks.io/simple-flink/content/) + diff --git a/markdown-file/Gitlab-Install-And-Settings.md b/markdown-file/Gitlab-Install-And-Settings.md new file mode 100644 index 00000000..c9a4c1e3 --- /dev/null +++ b/markdown-file/Gitlab-Install-And-Settings.md @@ -0,0 +1,297 @@ +# Gitlab 安装和配置 + +## Docker Compose 安装方式 + + +- 创建宿主机挂载目录:`mkdir -p /data/docker/gitlab/gitlab /data/docker/gitlab/redis /data/docker/gitlab/postgresql` +- 赋权(避免挂载的时候,一些程序需要容器中的用户的特定权限使用):`chown -R 777 /data/docker/gitlab/gitlab /data/docker/gitlab/redis /data/docker/gitlab/postgresql` +- 这里使用 docker-compose 的启动方式,所以需要创建 docker-compose.yml 文件: + +```yml +gitlab: + image: sameersbn/gitlab:10.4.2-1 + ports: + - "10022:22" + - "10080:80" + links: + - gitlab-redis:redisio + - gitlab-postgresql:postgresql + environment: + - GITLAB_PORT=80 + - GITLAB_SSH_PORT=22 + - GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alpha-numeric-string + - GITLAB_SECRETS_SECRET_KEY_BASE=long-and-random-alpha-numeric-string + - GITLAB_SECRETS_OTP_KEY_BASE=long-and-random-alpha-numeric-string + volumes: + - /data/docker/gitlab/gitlab:/home/git/data + restart: always +gitlab-redis: + image: sameersbn/redis + volumes: + - /data/docker/gitlab/redis:/var/lib/redis + restart: always +gitlab-postgresql: + image: sameersbn/postgresql:9.6-2 + environment: + - DB_NAME=gitlabhq_production + - DB_USER=gitlab + - DB_PASS=password + - DB_EXTENSION=pg_trgm + volumes: + - /data/docker/gitlab/postgresql:/var/lib/postgresql + restart: always +``` + +- 启动:`docker-compose up -d` +- 浏览器访问: + +## Gitlab 高可用方案(High Availability) + +- 官网: +- 本质就是把文件、缓存、数据库抽离出来,然后部署多个 Gitlab 用 nginx 前面做负载。 + + +## 原始安装方式(推荐) + +- 推荐至少内存 4G,它有大量组件 +- 有开源版本和收费版本,各版本比较: +- 官网: +- 中文网: +- 官网下载: +- 官网安装说明: +- 如果上面的下载比较慢,也有国内的镜像: + - 清华: +- 参考: + +``` +sudo yum install -y curl policycoreutils-python openssh-server + +sudo systemctl enable sshd +sudo systemctl start sshd + +curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash +sudo EXTERNAL_URL="http://192.168.1.123:8181" yum install -y gitlab-ce +``` + + +## 配置 + +- 配置域名 / IP + - 编辑配置文件:`sudo vim /etc/gitlab/gitlab.rb` + - 找到 13 行左右:`external_url 'http://gitlab.example.com'`,改为你的域名 / IP + - 刷新配置:`sudo gitlab-ctl reconfigure`,第一次这个时间会比较久,我花了好几分钟 + - 启动服务:`sudo gitlab-ctl start` + - 停止服务:`sudo gitlab-ctl stop` + - 重启服务:`sudo gitlab-ctl restart` +- 前面的初始化配置完成之后,访问当前机子 IP:`http://192.168.1.111:80` +- 默认用户是 `root`,并且没有密码,所以第一次访问是让你设置你的 root 密码,我设置为:gitlab123456(至少 8 位数) +- 设置会初始化密码之后,你就需要登录了。输入设置的密码。 +- root 管理员登录之后常用的设置地址(请求地址都是 RESTful 风格很好懂,也应该不会再变了。): + - 用户管理: + - 用户组管理: + - 项目管理: + - 添加 SSH Keys: + - 给新创建的用户设置密码: + - 新创建的用户,他首次登录会要求他强制修改密码的,这个设定很棒! +- 普通用户登录之后常去的链接: + - 配置 SSH Keys: + +## 配置 Jenkins 拉取代码权限 + +- Gitlab 创建一个 Access Token: + - 填写任意 Name 字符串 + - 勾选:API `Access the authenticated user's API` + - 点击:Create personal access token,会生成一个类似格式的字符串:`wt93jQzA8yu5a6pfsk3s`,这个 Jenkinsfile 会用到 +- 先访问 Jenkins 插件安装页面,安装下面三个插件: + - Gitlab:可能会直接安装不成功,如果不成功根据报错的详细信息可以看到 hpi 文件的下载地址,挂代理下载下来,然后离线安装即可 + - Gitlab Hook:用于触发 GitLab 的一些 WebHooks 来构建项目 + - Gitlab Authentication 这个插件提供了使用GitLab进行用户认证和授权的方案 +- 安装完插件后,访问 Jenkins 这个路径(Jenkins-->Credentials-->System-->Global credentials(unrestricted)-->Add Credentials) + - 该路径链接地址: + - kind 下拉框选择:`GitLab API token` + - token 就填写我们刚刚生成的 access token + - ID 填写我们 Gitlab 账号 + + +## 权限 + +- 官网帮助文档的权限说明: + +### 用户组的权限 + +- 用户组有这几种权限的概念:`Guest、Reporter、Developer、Master、Owner` +- 这个概念在设置用户组的时候会遇到,叫做:`Add user(s) to the group`,比如链接: + +|行为|Guest|Reporter|Developer|Master|Owner| +|---|---|--:|---|---|---| +|浏览组|✓|✓|✓|✓|✓| +|编辑组| | | | |✓| +|创建项目| | | |✓|✓| +|管理组成员| | | | |✓| +|移除组| | | | |✓| + +### 项目组的权限 + +- 项目组也有这几种权限的概念:`Guest、Reporter、Developer、Master、Owner` + - `Guest`:访客 + - `Reporter`:报告者; 可以理解为测试员、产品经理等,一般负责提交issue等 + - `Developer`:开发者; 负责开发 + - `Master`:主人; 一般是组长,负责对Master分支进行维护 + - `Owner`:拥有者; 一般是项目经理 +- 这个概念在项目设置的时候会遇到,叫做:`Members`,比如我有一个组下的项目链接: + +|行为|Guest|Reporter|Developer|Master|Owner| +|---|---|--:|---|---|---| +|创建issue|✓|✓|✓|✓|✓| +|留言评论|✓|✓|✓|✓|✓| +|更新代码| |✓|✓|✓|✓| +|下载工程| |✓|✓|✓|✓| +|创建代码片段| |✓|✓|✓|✓| +|创建合并请求| | |✓|✓|✓| +|创建新分支| | |✓|✓|✓| +|提交代码到非保护分支| | |✓|✓|✓| +|强制提交到非保护分支| | |✓|✓|✓| +|移除非保护分支| | |✓|✓|✓| +|添加tag| | |✓|✓|✓| +|创建wiki| | |✓|✓|✓| +|管理issue处理者| | |✓|✓|✓| +|管理labels| | |✓|✓|✓| +|创建里程碑| | | |✓|✓| +|添加项目成员| | | |✓|✓| +|提交保护分支| | | |✓|✓| +|使能分支保护| | | |✓|✓| +|修改/移除tag| | | |✓|✓| +|编辑工程| | | |✓|✓| +|添加deploy keys| | | |✓|✓| +|配置hooks| | | |✓|✓| +|切换visibility level| | | | |✓| +|切换工程namespace| | | | |✓| +|移除工程| | | | |✓| +|强制提交保护分支| | | | |✓| +|移除保护分支| | | | |✓| + +### 批量从一个项目中的成员转移到另外一个项目 + +- 项目的设置地址: + - 有一个 Import 按钮,跳转到: + +### 限定哪些分支可以提交、可以 merge + +- 也是在项目设置里面: +- 设置 CI (持续集成) 的 key 也是在这个地址上设置。 + + +## Gitlab 的其他功能使用 + +#### 创建用户 + +- 地址: +- 创建用户是没有填写密码的地方,默认是创建后会发送邮件给用户进行首次使用的密码设置。但是,有时候没必要这样,你可以创建好用户之后,编辑该用户就可以强制设置密码了(即使你设置了,第一次用户使用还是要让你修改密码...真是严苛) + + +#### 创建群组 + +- 地址: +- 群组主要有三种 Visibility Level: + - Private(私有,内部成员才能看到),The group and its projects can only be viewed by members. + - Internal(内部,只要能登录 Gitlab 就可以看到),The group and any internal projects can be viewed by any logged in user. + - Public(所有人都可以看到),The group and any public projects can be viewed without any authentication. + +#### 创建项目 + +- 地址: + +#### 增加 SSH keys + +- 地址: +- 官网指导: +- 新增 SSH keys:`ssh-keygen -t rsa -C "gitnavi@qq.com" -b 4096` +- linux 读取 SSH keys 值:`cat ~/.ssh/id_rsa.pub`,复制到 gitlab 配置页面 + + +## 使用 Gitlab 的一个开发流程 - Git flow + +- Git flow:我是翻译成:Git 开发流程建议(不是规范,适合大点的团队),也有一个插件叫做这个,本质是用插件来帮你引导做规范的流程管理。 +- 这几篇文章很好,不多说了: + - 比较起源的一个说明(英文): + - Git-flow 插件也是他开发的,插件地址: + - Git-flow 插件的一些相关资料: + - + - + - + - + - + - + + +## 接入第三方登录 + +- 官网文档: + - + - + - + +- gitlab 自己本身维护一套用户系统,第三方认证服务一套用户系统,gitlab 可以将两者关联起来,然后用户可以选择其中一种方式进行登录而已。 +- 所以,gitlab 第三方认证只能用于网页登录,clone 时仍然使用用户在 gitlab 的账户密码,推荐使用 ssh-key 来操作仓库,不再使用账户密码。 +- 重要参数:block_auto_created_users=true 的时候则自动注册的账户是被锁定的,需要管理员账户手动的为这些账户解锁,可以改为 false +- 编辑配置文件引入第三方:`sudo vim /etc/gitlab/gitlab.rb`,在 309 行有默认的一些注释配置 + - 其中 oauth2_generic 模块默认是没有,需要自己 gem,其他主流的那些都自带,配置即可使用。 + +``` +gitlab_rails['omniauth_enabled'] = true +gitlab_rails['omniauth_allow_single_sign_on'] = ['google_oauth2', 'facebook', 'twitter', 'oauth2_generic'] +gitlab_rails['omniauth_block_auto_created_users'] = false +gitlab_rails['omniauth_sync_profile_attributes'] = ['email','username'] +gitlab_rails['omniauth_external_providers'] = ['google_oauth2', 'facebook', 'twitter', 'oauth2_generic'] +gitlab_rails['omniauth_providers'] = [ + { + "name"=> "google_oauth2", + "label"=> "Google", + "app_id"=> "123456", + "app_secret"=> "123456", + "args"=> { + "access_type"=> 'offline', + "approval_prompt"=> '123456' + } + }, + { + "name"=> "facebook", + "label"=> "facebook", + "app_id"=> "123456", + "app_secret"=> "123456" + }, + { + "name"=> "twitter", + "label"=> "twitter", + "app_id"=> "123456", + "app_secret"=> "123456" + }, + { + "name" => "oauth2_generic", + "app_id" => "123456", + "app_secret" => "123456", + "args" => { + client_options: { + "site" => "http://sso.cdk8s.com:9090/sso", + "user_info_url" => "/oauth/userinfo" + }, + user_response_structure: { + root_path: ["user_attribute"], + attributes: { + "nickname": "username" + } + } + } + } +] + +``` + + +## 资料 + +- +- +- +- +- \ No newline at end of file diff --git a/markdown-file/Glances-Install-And-Settings.md b/markdown-file/Glances-Install-And-Settings.md new file mode 100644 index 00000000..9b4255b2 --- /dev/null +++ b/markdown-file/Glances-Install-And-Settings.md @@ -0,0 +1,68 @@ +# Glances 安装和配置 + +## Glances 介绍 + +- 相对 top、htop,它比较重,因此内容也比较多。小机子一般不建议安装。大机子一般也不建议一直开着。 +- 官网: +- 官网 Github: +- 官网文档: +- 当前(201810)最新版本为 3.0.2 + + +## Glances Linux 安装 + +- `curl -L https://bit.ly/glances | /bin/bash` +- 需要 5 ~ 10 分钟左右。 + +## 用法 + +#### 本地监控 + +- 进入实时监控面板(默认 3 秒一次指标):`glances` +- 每间隔 5 秒获取一次指标:`glances -t 5` +- 在控制面板中可以按快捷键进行排序、筛选 + +``` +m : 按内存占用排序进程 +p : 按进程名称排序进程 +c : 按 CPU 占用率排序进程 +i : 按 I/O 频率排序进程 +a : 自动排序进程 +d : 显示/隐藏磁盘 I/O 统计信息 +f : 显示/隐藏文件系统统计信息 +s : 显示/隐藏传感器统计信息 +y : 显示/隐藏硬盘温度统计信息 +l : 显示/隐藏日志 +n : 显示/隐藏网络统计信息 +x : 删除警告和严重日志 +h : 显示/隐藏帮助界面 +q : 退出 +w : 删除警告记录 +``` + + +#### 监控远程机子 + +- 这里面的检控方和被监控的概念要弄清楚 +- 作为服务端的机子运行(也就是被监控方):`glances -s` + - 假设它的 IP 为:192.168.1.44 + - 必需打开 61209 端口 +- 作为客户端的机子运行(要查看被检控方的数据):`glances -c 192.168.1.44` + - 这时候控制台输出的内容是被监控机子的数据 + + +## 导出数据 + +- 个人测试没效果,后续再看下吧。 +- 官网文档: +- 导出 CSV:`glances --export-csv /tmp/glances.csv` +- 导出 JSON:`glances --export-json /tmp/glances.json` + +## 资料 + +- +- +- +- +- +- diff --git a/markdown-file/GoAccess-Install-And-Settings.md b/markdown-file/GoAccess-Install-And-Settings.md new file mode 100644 index 00000000..26e0f920 --- /dev/null +++ b/markdown-file/GoAccess-Install-And-Settings.md @@ -0,0 +1,169 @@ +# GoAccess 安装和配置 + +## 官网资料 + +- 一般用于 Apache, Nginx 的 Log 分析 +- 官网: +- 官网下载(201807 最新版本 1.2): +- 官网 Github: +- 国内中文站: + + +## 安装(CentOS 7.4) + +- 注意,如果是在 CentOS 6 下安装会碰到一些问题,可以参考: + +- 1. 安装依赖包 + +``` +yum install -y ncurses-devel +wget http://geolite.maxmind.com/download/geoip/api/c/GeoIP.tar.gz +tar -zxvf GeoIP.tar.gz +cd GeoIP-1.4.8/ +./configure +make && make install +``` + +- 2. 安装 GoAccess + +``` +wget http://tar.goaccess.io/goaccess-1.2.tar.gz +tar -xzvf goaccess-1.2.tar.gz +cd goaccess-1.2/ +./configure --enable-utf8 --enable-geoip=legacy +make && make install +``` + +## 配置 + +- 假设你 nginx 安装在:`/usr/local/nginx` +- 假设你 nginx 的 log 输出到:`/var/log/nginx` +- 修改 `vim /usr/local/nginx/conf/nginx.conf` 指定 nginx 的日志格式 + +``` + +http { + charset utf8; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for" "$request_time"'; + + access_log /var/log/nginx/access.log main; + error_log /var/log/nginx/error.log; +} +``` + +- 停止 nginx:`/usr/local/nginx/sbin/nginx -s stop` +- 备份旧的 nginx log 文件:`mv /var/log/nginx/access.log /var/log/nginx/access.log.20180702back` +- 启动 nginx:`/usr/local/nginx/sbin/nginx` +- 创建 GoAccess 配置文件:`vim /etc/goaccess_log_conf_nginx.conf` + +``` +time-format %T +date-format %d/%b/%Y +log_format %h - %^ [%d:%t %^] "%r" %s %b "%R" "%u" "%^" %^ %^ %^ %T +``` + + +## 使用 + +#### 在终端上展示数据 + +``` +goaccess -a -d -f /var/log/nginx/access.log -p /etc/goaccess_log_conf_nginx.conf +``` + + +#### 手动生成当前统计页面 + +``` +goaccess -f /var/log/nginx/access.log -p /etc/goaccess_log_conf_nginx.conf -o /usr/local/nginx/report/index.html +``` + +- 更多参数用法: + +``` +时间分布图上:按小时展示数据: +goaccess -f /var/log/nginx/access.log -p /etc/goaccess_log_conf_nginx.conf -o /usr/local/nginx/report/index.html --ignore-crawlers --hour-spec=min + + +时间分布图上:按分钟展示数据: +goaccess -f /var/log/nginx/access.log -p /etc/goaccess_log_conf_nginx.conf -o /usr/local/nginx/report/index.html --ignore-crawlers --hour-spec=hour + + +不显示指定的面板 +goaccess -f /var/log/nginx/access.log -p /etc/goaccess_log_conf_nginx.conf -o /usr/local/nginx/report/index.html --ignore-crawlers --hour-spec=min \ + --ignore-panel=VISITORS \ + --ignore-panel=REQUESTS \ + --ignore-panel=REQUESTS_STATIC \ + --ignore-panel=NOT_FOUND \ + --ignore-panel=HOSTS \ + --ignore-panel=OS \ + --ignore-panel=BROWSERS \ + --ignore-panel=VIRTUAL_HOSTS \ + --ignore-panel=REFERRERS \ + --ignore-panel=REFERRING_SITES \ + --ignore-panel=KEYPHRASES \ + --ignore-panel=STATUS_CODES \ + --ignore-panel=REMOTE_USER \ + --ignore-panel=GEO_LOCATION + +我一般只留下几个面板(排除掉不想看的面板,因为使用 --enable-panel 参数无法达到这个目的) +goaccess -f /var/log/nginx/access.log -p /etc/goaccess_log_conf_nginx.conf -o /usr/local/nginx/report/index.html --ignore-crawlers --hour-spec=min \ + --ignore-panel=VISITORS \ + --ignore-panel=REQUESTS_STATIC \ + --ignore-panel=NOT_FOUND \ + --ignore-panel=OS \ + --ignore-panel=VIRTUAL_HOSTS \ + --ignore-panel=REFERRERS \ + --ignore-panel=KEYPHRASES \ + --ignore-panel=REMOTE_USER \ + --ignore-panel=GEO_LOCATION +``` + +#### 方便执行命令创建脚本 + +- `vim goaccess_report_by_min.sh` + +``` +goaccess -f /var/log/nginx/access.log -p /etc/goaccess_log_conf_nginx.conf -o /usr/local/nginx/report/index.html --ignore-crawlers --hour-spec=min \ + --ignore-panel=VISITORS \ + --ignore-panel=REQUESTS_STATIC \ + --ignore-panel=NOT_FOUND \ + --ignore-panel=OS \ + --ignore-panel=VIRTUAL_HOSTS \ + --ignore-panel=REFERRERS \ + --ignore-panel=KEYPHRASES \ + --ignore-panel=REMOTE_USER \ + --ignore-panel=GEO_LOCATION +``` + +- `vim goaccess_report_by_hour.sh` + +``` +goaccess -f /var/log/nginx/access.log -p /etc/goaccess_log_conf_nginx.conf -o /usr/local/nginx/report/index.html --ignore-crawlers --hour-spec=hour \ + --ignore-panel=VISITORS \ + --ignore-panel=REQUESTS_STATIC \ + --ignore-panel=NOT_FOUND \ + --ignore-panel=OS \ + --ignore-panel=VIRTUAL_HOSTS \ + --ignore-panel=REFERRERS \ + --ignore-panel=KEYPHRASES \ + --ignore-panel=REMOTE_USER \ + --ignore-panel=GEO_LOCATION +``` + +#### 实时生成统计页面 + +- 我个人看法是:一般没必要浪费这个性能,需要的时候执行下脚本就行了。 +- 官网文档:,查询关键字:**REAL TIME HTML OUTPUT** + +``` +goaccess -f /var/log/nginx/access.log -p /etc/goaccess_log_conf_nginx.conf -o /usr/local/nginx/report/index.html --real-time-html --daemonize +``` + +## 资料 + +- +- diff --git a/markdown-file/Grafana-Install-And-Settings.md b/markdown-file/Grafana-Install-And-Settings.md new file mode 100644 index 00000000..c0c12ae3 --- /dev/null +++ b/markdown-file/Grafana-Install-And-Settings.md @@ -0,0 +1,126 @@ +# Grafana 安装和配置 + + +## 对于版本 + +- [支持的 Elasticsearch 版本](http://docs.grafana.org/features/datasources/elasticsearch/#elasticsearch-version) + + +## Grafana Docker 安装 + +- 官网: + +``` +mkdir -p /data/docker/grafana/data +chmod 777 -R /data/docker/grafana/data + +docker run -d --name grafana -p 3000:3000 -v /data/docker/grafana/data:/var/lib/grafana grafana/grafana + +docker exec -it grafana /bin/bash + +容器中默认的配置文件位置:/etc/grafana/grafana.ini +复制出配置文件到宿主机:docker cp grafana:/etc/grafana/grafana.ini /Users/gitnavi/ +``` + +- +- 默认管理账号;admin,密码:admin,第一次登录后需要修改密码,也可以通过配置文件修改 + +``` +[security] +admin_user = admin +admin_password = admin +``` +---------------------------------------------------------------------------------------------- + +## Grafana 安装 + +- CentOS 7.4 +- rpm 文件包大小 53M +- 所需内存:300M 左右 +- 官网下载: +- 官网指导: + +``` +sudo yum install -y initscripts fontconfig urw-fonts +wget https://dl.grafana.com/oss/release/grafana-5.4.0-1.x86_64.rpm +sudo yum localinstall -y grafana-5.4.0-1.x86_64.rpm +``` + + +- 启动 Grafana 服务(默认是不启动的) + +``` +sudo systemctl start grafana-server +sudo systemctl status grafana-server +``` + +- 将 Grafana 服务设置为开机启动:`sudo systemctl enable grafana-server` +- 开放端口:`firewall-cmd --add-port=3000/tcp --permanent` +- 重新加载防火墙配置:`firewall-cmd --reload` +- 访问: +- 默认管理账号;admin,密码:admin,登录后需要修改密码 + +---------------------------------------------------------------------------------------------- + +## 配置 + +- 官网指导: +- 安装包默认安装后的一些路径 + - 二进制文件:`/usr/sbin/grafana-server` + - init.d 脚本:`/etc/init.d/grafana-server` + - 配置文件:`/etc/grafana/grafana.ini` + - 日志文件:`/var/log/grafana/grafana.log` + - 插件目录是:`/var/lib/grafana/plugins` + - 默认配置的 sqlite3 数据库:`/var/lib/grafana/grafana.db` +- 最重要的配置文件:`vim /etc/grafana/grafana.ini` + - 可以修改用户名和密码 + - 端口 + - 数据路径 + - 数据库配置 + - 第三方认证 + - Session 有效期 +- 添加数据源: +- 添加组织: +- 添加用户: +- 添加插件: +- 个性化设置: +- 软件变量: + +## 官网 dashboard + +- dashboar仓库地址: +- 本地可以通过输入 dashboard id 导入别人模板 +- 打开: + - 输入对应的 id,点击 Load 即可 + +---------------------------------------------------------------------------------------------- + +## 数据源 + +#### Elasticsearch + +使用: +- +- +- <> +- <> +- <> +- <> + + +---------------------------------------------------------------------------------------------- + + +## 其他资料 + +- +- <> +- <> +- <> +- <> +- <> +- <> +- <> +- <> +- <> + diff --git a/markdown-file/Hadoop-Install-And-Settings.md b/markdown-file/Hadoop-Install-And-Settings.md new file mode 100644 index 00000000..7f42810f --- /dev/null +++ b/markdown-file/Hadoop-Install-And-Settings.md @@ -0,0 +1,501 @@ +# Hadoop 安装和配置 + + +## Hadoop 说明 + +- Hadoop 官网: +- Hadoop 官网下载: + +## 基础环境 + +- 学习机器 2C4G(生产最少 8G): + - 172.16.0.17 + - 172.16.0.43 + - 172.16.0.180 +- 操作系统:CentOS 7.5 + - root 用户 +- 所有机子必备:Java:1.8 + - 确保:`echo $JAVA_HOME` 能查看到路径,并记下来路径 +- Hadoop:2.6.5 +- 关闭所有机子的防火墙:`systemctl stop firewalld.service` + +## 集群环境设置 + +- Hadoop 集群具体来说包含两个集群:HDFS 集群和 YARN 集群,两者逻辑上分离,但物理上常在一起 + - HDFS 集群:负责海量数据的存储,集群中的角色主要有 NameNode / DataNode + - YARN 集群:负责海量数据运算时的资源调度,集群中的角色主要有 ResourceManager /NodeManager + - HDFS 采用 master/worker 架构。一个 HDFS 集群是由一个 Namenode 和一定数目的 Datanodes 组成。Namenode 是一个中心服务器,负责管理文件系统的命名空间 (namespace) 以及客户端对文件的访问。集群中的 Datanode 一般是一个节点一个,负责管理它所在节点上的存储。 +- 分别给三台机子设置 hostname + +``` +hostnamectl --static set-hostname linux01 +hostnamectl --static set-hostname linux02 +hostnamectl --static set-hostname linux03 +``` + + +- 修改 hosts + +``` +就按这个来,其他多余的别加,不然可能也会有影响 +vim /etc/hosts +172.16.0.17 linux01 +172.16.0.43 linux02 +172.16.0.180 linux03 +``` + + +- 对 linux01 设置免密: + +``` +生产密钥对 +ssh-keygen -t rsa + + +公钥内容写入 authorized_keys +cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys + +测试: +ssh localhost + +``` + +- 将公钥复制到两台 slave + - 如果你是采用 pem 登录的,可以看这个:[SSH 免密登录](SSH-login-without-password.md) + +``` +ssh-copy-id -i ~/.ssh/id_rsa.pub -p 22 root@172.16.0.43,根据提示输入 linux02 机器的 root 密码,成功会有相应提示 +ssh-copy-id -i ~/.ssh/id_rsa.pub -p 22 root@172.16.0.180,根据提示输入 linux03 机器的 root 密码,成功会有相应提示 + + +在 linux01 上测试: +ssh linux02 +ssh linux03 + +``` + + + +## Hadoop 安装 + +- 关于版本这件事,主要看你的技术生态圈。如果你的其他技术,比如 Spark,Flink 等不支持最新版,则就只能向下考虑。 +- 我这里技术栈,目前只能到:2.6.5,所以下面的内容都是基于 2.6.5 版本 +- 官网说明: +- 分别在三台机子上都创建目录: + +``` +mkdir -p /data/hadoop/hdfs/name /data/hadoop/hdfs/data /data/hadoop/hdfs/tmp +``` + +- 下载 Hadoop: +- 现在 linux01 机子上安装 + +``` +cd /usr/local && wget http://apache.claz.org/hadoop/common/hadoop-2.6.5/hadoop-2.6.5.tar.gz +tar zxvf hadoop-2.6.5.tar.gz,有 191M 左右 +``` + +- **给三台机子都先设置 HADOOP_HOME** + - 会 ansible playbook 会方便点:[Ansible 安装和配置](Ansible-Install-And-Settings.md) + +``` +vim /etc/profile + +export HADOOP_HOME=/usr/local/hadoop-2.6.5 +export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin + +source /etc/profile +``` + + +## 修改 linux01 配置 + + +``` +修改 JAVA_HOME +vim $HADOOP_HOME/etc/hadoop/hadoop-env.sh + +把 25 行的 +export JAVA_HOME=${JAVA_HOME} +都改为 +export JAVA_HOME=/usr/local/jdk1.8.0_191 + + +vim $HADOOP_HOME/etc/hadoop/yarn-env.sh + +文件开头加一行 export JAVA_HOME=/usr/local/jdk1.8.0_191 + +``` + +- hadoop.tmp.dir == 指定hadoop运行时产生文件的存储目录 + +``` + +vim $HADOOP_HOME/etc/hadoop/core-site.xml,改为: + + + + hadoop.tmp.dir + file:/data/hadoop/hdfs/tmp + + + io.file.buffer.size + 131072 + + + + fs.defaultFS + hdfs://linux01:9000 + + + hadoop.proxyuser.root.hosts + * + + + hadoop.proxyuser.root.groups + * + + +``` + + +- 配置包括副本数量 + - 最大值是 datanode 的个数 +- 数据存放目录 + +``` +vim $HADOOP_HOME/etc/hadoop/hdfs-site.xml + + + + dfs.replication + 2 + + + dfs.namenode.name.dir + file:/data/hadoop/hdfs/name + true + + + dfs.datanode.data.dir + file:/data/hadoop/hdfs/data + true + + + dfs.webhdfs.enabled + true + + + dfs.permissions + false + + + +``` + + + +- 设置 YARN + +``` +新创建:vim $HADOOP_HOME/etc/hadoop/mapred-site.xml + + + + + mapreduce.framework.name + yarn + + + + mapreduce.map.memory.mb + 4096 + + + + mapreduce.reduce.memory.mb + 8192 + + + + mapreduce.map.java.opts + -Xmx3072m + + + + mapreduce.reduce.java.opts + -Xmx6144m + + + +``` + + +- yarn.resourcemanager.hostname == 指定YARN的老大(ResourceManager)的地址 +- yarn.nodemanager.aux-services == NodeManager上运行的附属服务。需配置成mapreduce_shuffle,才可运行MapReduce程序默认值:"" +- 32G 内存的情况下配置: + +``` +vim $HADOOP_HOME/etc/hadoop/yarn-site.xml + + + + + yarn.resourcemanager.hostname + linux01 + + + + yarn.nodemanager.aux-services + mapreduce_shuffle + + + + yarn.nodemanager.vmem-pmem-ratio + 2.1 + + + + yarn.nodemanager.resource.memory-mb + 20480 + + + + yarn.scheduler.minimum-allocation-mb + 2048 + + + +``` + + +- 配置 slave 相关信息 + + +``` +vim $HADOOP_HOME/etc/hadoop/slaves + +把默认的配置里面的 localhost 删除,换成: +linux02 +linux03 + +``` + + +``` +scp -r /usr/local/hadoop-2.6.5 root@linux02:/usr/local/ + +scp -r /usr/local/hadoop-2.6.5 root@linux03:/usr/local/ + +``` + + +## linux01 机子运行 + +``` +格式化 HDFS +hdfs namenode -format + +``` + +- 输出结果: + +``` +[root@linux01 hadoop-2.6.5]# hdfs namenode -format +18/12/17 17:47:17 INFO namenode.NameNode: STARTUP_MSG: +/************************************************************ +STARTUP_MSG: Starting NameNode +STARTUP_MSG: host = localhost/127.0.0.1 +STARTUP_MSG: args = [-format] +STARTUP_MSG: version = 2.6.5 +STARTUP_MSG: classpath = /usr/local/hadoop-2.6.5/etc/hadoop:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/apacheds-kerberos-codec-2.0.0-M15.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/commons-io-2.4.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/activation-1.1.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/netty-3.6.2.Final.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jackson-mapper-asl-1.9.13.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/slf4j-api-1.7.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/junit-4.11.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/curator-recipes-2.6.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jasper-compiler-5.5.23.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jets3t-0.9.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/commons-lang-2.6.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/commons-digester-1.8.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jackson-core-asl-1.9.13.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/apacheds-i18n-2.0.0-M15.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/guava-11.0.2.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/gson-2.2.4.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jackson-jaxrs-1.9.13.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jettison-1.1.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jetty-6.1.26.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/api-util-1.0.0-M20.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/log4j-1.2.17.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/commons-beanutils-core-1.8.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/commons-httpclient-3.1.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/commons-el-1.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/paranamer-2.3.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/slf4j-log4j12-1.7.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/commons-collections-3.2.2.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jersey-server-1.9.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/commons-net-3.1.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/hadoop-auth-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jasper-runtime-5.5.23.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jaxb-impl-2.2.3-1.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/hamcrest-core-1.3.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/stax-api-1.0-2.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/commons-beanutils-1.7.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/protobuf-java-2.5.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/curator-framework-2.6.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/xz-1.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jsr305-1.3.9.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jsp-api-2.1.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/commons-compress-1.4.1.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/asm-3.2.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jsch-0.1.42.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/commons-configuration-1.6.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/commons-cli-1.2.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jackson-xc-1.9.13.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/commons-logging-1.1.3.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/htrace-core-3.0.4.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jetty-util-6.1.26.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/commons-math3-3.1.1.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/mockito-all-1.8.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jersey-json-1.9.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/zookeeper-3.4.6.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/httpclient-4.2.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/servlet-api-2.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/xmlenc-0.52.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/httpcore-4.2.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/api-asn1-api-1.0.0-M20.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/java-xmlbuilder-0.4.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/avro-1.7.4.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jaxb-api-2.2.2.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/commons-codec-1.4.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/jersey-core-1.9.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/snappy-java-1.0.4.1.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/curator-client-2.6.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/lib/hadoop-annotations-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/hadoop-common-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/hadoop-common-2.6.5-tests.jar:/usr/local/hadoop-2.6.5/share/hadoop/common/hadoop-nfs-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/commons-io-2.4.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/netty-3.6.2.Final.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/jackson-mapper-asl-1.9.13.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/commons-lang-2.6.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/commons-daemon-1.0.13.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/jackson-core-asl-1.9.13.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/guava-11.0.2.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/jetty-6.1.26.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/log4j-1.2.17.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/commons-el-1.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/xercesImpl-2.9.1.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/jersey-server-1.9.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/jasper-runtime-5.5.23.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/protobuf-java-2.5.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/jsr305-1.3.9.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/xml-apis-1.3.04.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/jsp-api-2.1.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/asm-3.2.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/commons-cli-1.2.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/commons-logging-1.1.3.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/htrace-core-3.0.4.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/jetty-util-6.1.26.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/servlet-api-2.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/xmlenc-0.52.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/commons-codec-1.4.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/lib/jersey-core-1.9.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/hadoop-hdfs-2.6.5-tests.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/hadoop-hdfs-nfs-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/hdfs/hadoop-hdfs-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/commons-io-2.4.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/activation-1.1.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/aopalliance-1.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/netty-3.6.2.Final.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jackson-mapper-asl-1.9.13.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/commons-lang-2.6.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jackson-core-asl-1.9.13.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/guice-3.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/guava-11.0.2.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jackson-jaxrs-1.9.13.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jettison-1.1.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jetty-6.1.26.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/log4j-1.2.17.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/commons-httpclient-3.1.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/commons-collections-3.2.2.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jersey-server-1.9.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jaxb-impl-2.2.3-1.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/stax-api-1.0-2.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/protobuf-java-2.5.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/xz-1.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jsr305-1.3.9.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jersey-client-1.9.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/guice-servlet-3.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/commons-compress-1.4.1.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/asm-3.2.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/commons-cli-1.2.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jersey-guice-1.9.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jackson-xc-1.9.13.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/commons-logging-1.1.3.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jetty-util-6.1.26.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/leveldbjni-all-1.8.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jersey-json-1.9.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/javax.inject-1.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/zookeeper-3.4.6.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/servlet-api-2.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jaxb-api-2.2.2.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jline-0.9.94.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/commons-codec-1.4.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jersey-core-1.9.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/hadoop-yarn-server-web-proxy-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/hadoop-yarn-api-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/hadoop-yarn-server-common-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/hadoop-yarn-registry-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/hadoop-yarn-server-nodemanager-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/hadoop-yarn-client-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/hadoop-yarn-common-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/hadoop-yarn-applications-unmanaged-am-launcher-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/hadoop-yarn-server-tests-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/hadoop-yarn-server-resourcemanager-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/hadoop-yarn-server-applicationhistoryservice-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/yarn/hadoop-yarn-applications-distributedshell-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/commons-io-2.4.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/aopalliance-1.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/netty-3.6.2.Final.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/jackson-mapper-asl-1.9.13.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/junit-4.11.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/jackson-core-asl-1.9.13.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/guice-3.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/log4j-1.2.17.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/paranamer-2.3.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/jersey-server-1.9.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/hamcrest-core-1.3.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/protobuf-java-2.5.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/xz-1.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/guice-servlet-3.0.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/commons-compress-1.4.1.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/asm-3.2.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/jersey-guice-1.9.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/leveldbjni-all-1.8.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/javax.inject-1.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/avro-1.7.4.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/jersey-core-1.9.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/snappy-java-1.0.4.1.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/lib/hadoop-annotations-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/hadoop-mapreduce-client-app-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/hadoop-mapreduce-client-common-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/hadoop-mapreduce-client-shuffle-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/hadoop-mapreduce-client-core-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/hadoop-mapreduce-client-hs-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/hadoop-mapreduce-client-hs-plugins-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.5.jar:/usr/local/hadoop-2.6.5/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.6.5-tests.jar:/usr/local/hadoop-2.6.5/contrib/capacity-scheduler/*.jar +STARTUP_MSG: build = https://github.com/apache/hadoop.git -r e8c9fe0b4c252caf2ebf1464220599650f119997; compiled by 'sjlee' on 2016-10-02T23:43Z +STARTUP_MSG: java = 1.8.0_191 +************************************************************/ +18/12/17 17:47:17 INFO namenode.NameNode: registered UNIX signal handlers for [TERM, HUP, INT] +18/12/17 17:47:17 INFO namenode.NameNode: createNameNode [-format] +Formatting using clusterid: CID-beba43b4-0881-48b4-8eda-5c3bca046398 +18/12/17 17:47:17 INFO namenode.FSNamesystem: No KeyProvider found. +18/12/17 17:47:17 INFO namenode.FSNamesystem: fsLock is fair:true +18/12/17 17:47:17 INFO blockmanagement.DatanodeManager: dfs.block.invalidate.limit=1000 +18/12/17 17:47:17 INFO blockmanagement.DatanodeManager: dfs.namenode.datanode.registration.ip-hostname-check=true +18/12/17 17:47:17 INFO blockmanagement.BlockManager: dfs.namenode.startup.delay.block.deletion.sec is set to 000:00:00:00.000 +18/12/17 17:47:17 INFO blockmanagement.BlockManager: The block deletion will start around 2018 Dec 17 17:47:17 +18/12/17 17:47:17 INFO util.GSet: Computing capacity for map BlocksMap +18/12/17 17:47:17 INFO util.GSet: VM type = 64-bit +18/12/17 17:47:17 INFO util.GSet: 2.0% max memory 889 MB = 17.8 MB +18/12/17 17:47:17 INFO util.GSet: capacity = 2^21 = 2097152 entries +18/12/17 17:47:17 INFO blockmanagement.BlockManager: dfs.block.access.token.enable=false +18/12/17 17:47:17 INFO blockmanagement.BlockManager: defaultReplication = 2 +18/12/17 17:47:17 INFO blockmanagement.BlockManager: maxReplication = 512 +18/12/17 17:47:17 INFO blockmanagement.BlockManager: minReplication = 1 +18/12/17 17:47:17 INFO blockmanagement.BlockManager: maxReplicationStreams = 2 +18/12/17 17:47:17 INFO blockmanagement.BlockManager: replicationRecheckInterval = 3000 +18/12/17 17:47:17 INFO blockmanagement.BlockManager: encryptDataTransfer = false +18/12/17 17:47:17 INFO blockmanagement.BlockManager: maxNumBlocksToLog = 1000 +18/12/17 17:47:17 INFO namenode.FSNamesystem: fsOwner = root (auth:SIMPLE) +18/12/17 17:47:17 INFO namenode.FSNamesystem: supergroup = supergroup +18/12/17 17:47:17 INFO namenode.FSNamesystem: isPermissionEnabled = false +18/12/17 17:47:17 INFO namenode.FSNamesystem: HA Enabled: false +18/12/17 17:47:17 INFO namenode.FSNamesystem: Append Enabled: true +18/12/17 17:47:17 INFO util.GSet: Computing capacity for map INodeMap +18/12/17 17:47:17 INFO util.GSet: VM type = 64-bit +18/12/17 17:47:17 INFO util.GSet: 1.0% max memory 889 MB = 8.9 MB +18/12/17 17:47:17 INFO util.GSet: capacity = 2^20 = 1048576 entries +18/12/17 17:47:17 INFO namenode.NameNode: Caching file names occuring more than 10 times +18/12/17 17:47:17 INFO util.GSet: Computing capacity for map cachedBlocks +18/12/17 17:47:17 INFO util.GSet: VM type = 64-bit +18/12/17 17:47:17 INFO util.GSet: 0.25% max memory 889 MB = 2.2 MB +18/12/17 17:47:17 INFO util.GSet: capacity = 2^18 = 262144 entries +18/12/17 17:47:17 INFO namenode.FSNamesystem: dfs.namenode.safemode.threshold-pct = 0.9990000128746033 +18/12/17 17:47:17 INFO namenode.FSNamesystem: dfs.namenode.safemode.min.datanodes = 0 +18/12/17 17:47:17 INFO namenode.FSNamesystem: dfs.namenode.safemode.extension = 30000 +18/12/17 17:47:17 INFO namenode.FSNamesystem: Retry cache on namenode is enabled +18/12/17 17:47:17 INFO namenode.FSNamesystem: Retry cache will use 0.03 of total heap and retry cache entry expiry time is 600000 millis +18/12/17 17:47:17 INFO util.GSet: Computing capacity for map NameNodeRetryCache +18/12/17 17:47:17 INFO util.GSet: VM type = 64-bit +18/12/17 17:47:17 INFO util.GSet: 0.029999999329447746% max memory 889 MB = 273.1 KB +18/12/17 17:47:17 INFO util.GSet: capacity = 2^15 = 32768 entries +18/12/17 17:47:17 INFO namenode.NNConf: ACLs enabled? false +18/12/17 17:47:17 INFO namenode.NNConf: XAttrs enabled? true +18/12/17 17:47:17 INFO namenode.NNConf: Maximum size of an xattr: 16384 +18/12/17 17:47:17 INFO namenode.FSImage: Allocated new BlockPoolId: BP-233285725-127.0.0.1-1545040037972 +18/12/17 17:47:18 INFO common.Storage: Storage directory /data/hadoop/hdfs/name has been successfully formatted. +18/12/17 17:47:18 INFO namenode.FSImageFormatProtobuf: Saving image file /data/hadoop/hdfs/name/current/fsimage.ckpt_0000000000000000000 using no compression +18/12/17 17:47:18 INFO namenode.FSImageFormatProtobuf: Image file /data/hadoop/hdfs/name/current/fsimage.ckpt_0000000000000000000 of size 321 bytes saved in 0 seconds. +18/12/17 17:47:18 INFO namenode.NNStorageRetentionManager: Going to retain 1 images with txid >= 0 +18/12/17 17:47:18 INFO util.ExitUtil: Exiting with status 0 +18/12/17 17:47:18 INFO namenode.NameNode: SHUTDOWN_MSG: +/************************************************************ +SHUTDOWN_MSG: Shutting down NameNode at localhost/127.0.0.1 +************************************************************/ + +``` + +## HDFS 启动 + +- 启动:start-dfs.sh,根据提示一路 yes + +``` +这个命令效果: +主节点会启动任务:NameNode 和 SecondaryNameNode +从节点会启动任务:DataNode + + +主节点查看:jps,可以看到: +21922 Jps +21603 NameNode +21787 SecondaryNameNode + + +从节点查看:jps 可以看到: +19728 DataNode +19819 Jps +``` + + +- 查看运行更多情况:`hdfs dfsadmin -report` + +``` +Configured Capacity: 0 (0 B) +Present Capacity: 0 (0 B) +DFS Remaining: 0 (0 B) +DFS Used: 0 (0 B) +DFS Used%: NaN% +Under replicated blocks: 0 +Blocks with corrupt replicas: 0 +Missing blocks: 0 +``` + +- 如果需要停止:`stop-dfs.sh` +- 查看 log:`cd $HADOOP_HOME/logs` + + +## YARN 运行 + +``` +start-yarn.sh +然后 jps 你会看到一个:ResourceManager + +从节点你会看到:NodeManager + +停止:stop-yarn.sh + +``` + +## 端口情况 + +- 主节点当前运行的所有端口:`netstat -tpnl | grep java` +- 会用到端口(为了方便展示,整理下顺序): + +``` +tcp 0 0 172.16.0.17:9000 0.0.0.0:* LISTEN 22932/java >> NameNode +tcp 0 0 0.0.0.0:50070 0.0.0.0:* LISTEN 22932/java >> NameNode +tcp 0 0 0.0.0.0:50090 0.0.0.0:* LISTEN 23125/java >> SecondaryNameNode +tcp6 0 0 172.16.0.17:8030 :::* LISTEN 23462/java >> ResourceManager +tcp6 0 0 172.16.0.17:8031 :::* LISTEN 23462/java >> ResourceManager +tcp6 0 0 172.16.0.17:8032 :::* LISTEN 23462/java >> ResourceManager +tcp6 0 0 172.16.0.17:8033 :::* LISTEN 23462/java >> ResourceManager +tcp6 0 0 172.16.0.17:8088 :::* LISTEN 23462/java >> ResourceManager +``` + +- 从节点当前运行的所有端口:`netstat -tpnl | grep java` +- 会用到端口(为了方便展示,整理下顺序): + +``` +tcp 0 0 0.0.0.0:50010 0.0.0.0:* LISTEN 14545/java >> DataNode +tcp 0 0 0.0.0.0:50020 0.0.0.0:* LISTEN 14545/java >> DataNode +tcp 0 0 0.0.0.0:50075 0.0.0.0:* LISTEN 14545/java >> DataNode +tcp6 0 0 :::8040 :::* LISTEN 14698/java >> NodeManager +tcp6 0 0 :::8042 :::* LISTEN 14698/java >> NodeManager +tcp6 0 0 :::13562 :::* LISTEN 14698/java >> NodeManager +tcp6 0 0 :::37481 :::* LISTEN 14698/java >> NodeManager +``` + +------------------------------------------------------------------- + +## 管理界面 + +- 查看 HDFS NameNode 管理界面: +- 访问 YARN ResourceManager 管理界面: +- 访问 NodeManager-1 管理界面: +- 访问 NodeManager-2 管理界面: + + +------------------------------------------------------------------- + +## 运行作业 + +- 在主节点上操作 +- 运行一个 Mapreduce 作业试试: + - 计算 π:`hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.5.jar pi 5 10` +- 运行一个文件相关作业: + - 由于运行 hadoop 时指定的输入文件只能是 HDFS 文件系统中的文件,所以我们必须将要进行 wordcount 的文件从本地文件系统拷贝到 HDFS 文件系统中。 + - 查看目前根目录结构:`hadoop fs -ls /` + - 查看目前根目录结构,另外写法:`hadoop fs -ls hdfs://linux-05:9000/` + - 或者列出目录以及下面的文件:`hadoop fs -ls -R /` + - 更多命令可以看:[hadoop HDFS常用文件操作命令](https://segmentfault.com/a/1190000002672666) + - 创建目录:`hadoop fs -mkdir -p /tmp/zch/wordcount_input_dir` + - 上传文件:`hadoop fs -put /opt/input.txt /tmp/zch/wordcount_input_dir` + - 查看上传的目录下是否有文件:`hadoop fs -ls /tmp/zch/wordcount_input_dir` + - 向 yarn 提交作业,计算单词个数:`hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.5.jar wordcount /tmp/zch/wordcount_input_dir /tmp/zch/wordcount_output_dir` + - 查看计算结果输出的目录:`hadoop fs -ls /tmp/zch/wordcount_output_dir` + - 查看计算结果输出内容:`hadoop fs -cat /tmp/zch/wordcount_output_dir/part-r-00000` +- 查看正在运行的 Hadoop 任务:`yarn application -list` +- 关闭 Hadoop 任务进程:`yarn application -kill 你的ApplicationId` + + +------------------------------------------------------------------- + +## 资料 + +- [如何正确的为 MapReduce 配置内存分配](http://loupipalien.com/2018/03/how-to-properly-configure-the-memory-allocations-for-mapreduce/) +- +- +- +- \ No newline at end of file diff --git a/markdown-file/Harbor-Install-And-Usage.md b/markdown-file/Harbor-Install-And-Usage.md new file mode 100644 index 00000000..38a437e2 --- /dev/null +++ b/markdown-file/Harbor-Install-And-Usage.md @@ -0,0 +1,439 @@ +# Harbor 安装和配置 + +## 环境说明 + +- CentOS 7.4 +- IP:`192.168.0.105` +- 需要访问的机子 hosts 需要映射(如果绑定真实域名就不需要这一步了):`192.168.0.105 harbor.gitnavi.com` + - 直接用 IP 也是可以的,只是不用起来不美观 + +## 官方文档 + +- 安装指导: + - 从中我们可以知道需要:[Docker、Docker Compose 环境](./Docker-Install-And-Usage.md) +- 硬件最低要求:2C + 4GB(推荐 8GB) + - 官网有推荐配置说明:[hardware](https://github.com/goharbor/harbor/blob/master/docs/installation_guide.md#hardware) +- 下载: + - 当前(201806)最新版本:**v1.5.1** + - 当前(201810)最新版本:**v1.5.3 和 1.6.0** + - 分 offline 和 online 版本,推荐使用 offline + - **v1.5.1** 下载地址: + - **v1.5.3** 下载地址: + + +## 安装 + +- 切换目录:`cd /opt/setups` +- 下载:`wget https://storage.googleapis.com/harbor-releases/release-1.5.0/harbor-offline-installer-v1.5.1.tgz` +- 解压:`tar xvf harbor-offline-installer-v1.5.1.tgz` +- 移动到 /usr 目录下:`mv /opt/setups/harbor /usr/local` +- 修改配置文件:`vim /usr/local/harbor/harbor.cfg`: + +``` +_version = 1.5.0 + +# hostname 可以使用 ip、域名,不可以设置为 127.0.0.1 或 localhost +hostname = harbor.gitnavi.com + +ui_url_protocol = http +max_job_workers = 50 +customize_crt = on +ssl_cert = /data/cert/server.crt +ssl_cert_key = /data/cert/server.key +secretkey_path = /data +admiral_url = NA +log_rotate_count = 50 +log_rotate_size = 200M +http_proxy = +https_proxy = +no_proxy = 127.0.0.1,localhost,ui +email_identity = +email_server = smtp.mydomain.com +email_server_port = 25 +email_username = sample_admin@mydomain.com +email_password = abc +email_from = admin +email_ssl = false +email_insecure = false + +# 启动Harbor后,管理员UI登录的密码,默认是 Harbor12345,用户名默认是:admin +harbor_admin_password = Harbor12345 + +auth_mode = db_auth +ldap_url = ldaps://ldap.mydomain.com +ldap_basedn = ou=people,dc=mydomain,dc=com +ldap_uid = uid +ldap_scope = 2 +ldap_timeout = 5 +ldap_verify_cert = true +ldap_group_basedn = ou=group,dc=mydomain,dc=com +ldap_group_filter = objectclass=group +ldap_group_gid = cn +ldap_group_scope = 2 +self_registration = on +token_expiration = 30 +project_creation_restriction = everyone +db_host = mysql +db_password = root123 +db_port = 3306 +db_user = root +redis_url = redis:6379 +clair_db_host = postgres +clair_db_password = password +clair_db_port = 5432 +clair_db_username = postgres +clair_db = postgres +uaa_endpoint = uaa.mydomain.org +uaa_clientid = id +uaa_clientsecret = secret +uaa_verify_cert = true +uaa_ca_cert = /path/to/ca.pem +registry_storage_provider_name = filesystem +registry_storage_provider_config = +``` + +- 安装成功会占用这些端口,所以请先做好准备,如果不想使用下面的端口需要修改:`vim /usr/local/harbor/docker-compose.yml` + - `80` + - `6379` + - `3306` + - `5000` + - `1514` +- 后面重新启动 Harbor 也靠这个文件了:`docker-compose -f /usr/local/harbor/docker-compose.yml restart` +- 开始安装:`sh /usr/local/harbor/install.sh`,控制台输出如下(预计需要 5 ~ 10 分钟): + +``` + +[Step 0]: checking installation environment ... + +Note: docker version: 17.12.0 + +Note: docker-compose version: 1.18.0 + +[Step 1]: loading Harbor images ... +52ef9064d2e4: Loading layer [==================================================>] 135.9MB/135.9MB +4a6862dbadda: Loading layer [==================================================>] 23.25MB/23.25MB +58b7d0c522b2: Loading layer [==================================================>] 24.4MB/24.4MB +9cd4bb748634: Loading layer [==================================================>] 7.168kB/7.168kB +c81302a14908: Loading layer [==================================================>] 10.56MB/10.56MB +7848e9ba72a3: Loading layer [==================================================>] 24.39MB/24.39MB +Loaded image: vmware/harbor-ui:v1.5.1 +f1691b5a5198: Loading layer [==================================================>] 73.15MB/73.15MB +a529013c99e4: Loading layer [==================================================>] 3.584kB/3.584kB +d9b4853cff8b: Loading layer [==================================================>] 3.072kB/3.072kB +3d305073979e: Loading layer [==================================================>] 4.096kB/4.096kB +c9e17074f54a: Loading layer [==================================================>] 3.584kB/3.584kB +956055840e30: Loading layer [==================================================>] 9.728kB/9.728kB +Loaded image: vmware/harbor-log:v1.5.1 +185db06a02d0: Loading layer [==================================================>] 23.25MB/23.25MB +835213979c70: Loading layer [==================================================>] 20.9MB/20.9MB +f74eeb41c1c9: Loading layer [==================================================>] 20.9MB/20.9MB +Loaded image: vmware/harbor-jobservice:v1.5.1 +9bd5c7468774: Loading layer [==================================================>] 23.25MB/23.25MB +5fa6889b9a6d: Loading layer [==================================================>] 2.56kB/2.56kB +bd3ac235b209: Loading layer [==================================================>] 2.56kB/2.56kB +cb5d493833cc: Loading layer [==================================================>] 2.048kB/2.048kB +557669a074de: Loading layer [==================================================>] 22.8MB/22.8MB +f02b4f30a9ac: Loading layer [==================================================>] 22.8MB/22.8MB +Loaded image: vmware/registry-photon:v2.6.2-v1.5.1 +5d3b562db23e: Loading layer [==================================================>] 23.25MB/23.25MB +8edca1b0e3b0: Loading layer [==================================================>] 12.16MB/12.16MB +ce5f11ea46c0: Loading layer [==================================================>] 17.3MB/17.3MB +93750d7ec363: Loading layer [==================================================>] 15.87kB/15.87kB +36f81937e80d: Loading layer [==================================================>] 3.072kB/3.072kB +37e5df92b624: Loading layer [==================================================>] 29.46MB/29.46MB +Loaded image: vmware/notary-server-photon:v0.5.1-v1.5.1 +0a2f8f90bd3a: Loading layer [==================================================>] 401.3MB/401.3MB +41fca4deb6bf: Loading layer [==================================================>] 9.216kB/9.216kB +f2e28262e760: Loading layer [==================================================>] 9.216kB/9.216kB +68677196e356: Loading layer [==================================================>] 7.68kB/7.68kB +2b006714574e: Loading layer [==================================================>] 1.536kB/1.536kB +Loaded image: vmware/mariadb-photon:v1.5.1 +a8c4992c632e: Loading layer [==================================================>] 156.3MB/156.3MB +0f37bf842677: Loading layer [==================================================>] 10.75MB/10.75MB +9f34c0cd38bf: Loading layer [==================================================>] 2.048kB/2.048kB +91ca17ca7e16: Loading layer [==================================================>] 48.13kB/48.13kB +5a7e0da65127: Loading layer [==================================================>] 10.8MB/10.8MB +Loaded image: vmware/clair-photon:v2.0.1-v1.5.1 +0e782fe069e7: Loading layer [==================================================>] 23.25MB/23.25MB +67fc1e2f7009: Loading layer [==================================================>] 15.36MB/15.36MB +8db2141aa82c: Loading layer [==================================================>] 15.36MB/15.36MB +Loaded image: vmware/harbor-adminserver:v1.5.1 +3f87a34f553c: Loading layer [==================================================>] 4.772MB/4.772MB +Loaded image: vmware/nginx-photon:v1.5.1 +Loaded image: vmware/photon:1.0 +ad58f3ddcb1b: Loading layer [==================================================>] 10.95MB/10.95MB +9b50f12509bf: Loading layer [==================================================>] 17.3MB/17.3MB +2c21090fd212: Loading layer [==================================================>] 15.87kB/15.87kB +38bec864f23e: Loading layer [==================================================>] 3.072kB/3.072kB +6e81ea7b0fa6: Loading layer [==================================================>] 28.24MB/28.24MB +Loaded image: vmware/notary-signer-photon:v0.5.1-v1.5.1 +897a26fa09cb: Loading layer [==================================================>] 95.02MB/95.02MB +16e3a10a21ba: Loading layer [==================================================>] 6.656kB/6.656kB +85ecac164331: Loading layer [==================================================>] 2.048kB/2.048kB +37a2fb188706: Loading layer [==================================================>] 7.68kB/7.68kB +Loaded image: vmware/postgresql-photon:v1.5.1 +bed9f52be1d1: Loading layer [==================================================>] 11.78kB/11.78kB +d731f2986f6e: Loading layer [==================================================>] 2.56kB/2.56kB +c3fde9a69f96: Loading layer [==================================================>] 3.072kB/3.072kB +Loaded image: vmware/harbor-db:v1.5.1 +7844feb13ef3: Loading layer [==================================================>] 78.68MB/78.68MB +de0fd8aae388: Loading layer [==================================================>] 3.072kB/3.072kB +3f79efb720fd: Loading layer [==================================================>] 59.9kB/59.9kB +1c02f801c2e8: Loading layer [==================================================>] 61.95kB/61.95kB +Loaded image: vmware/redis-photon:v1.5.1 +454c81edbd3b: Loading layer [==================================================>] 135.2MB/135.2MB +e99db1275091: Loading layer [==================================================>] 395.4MB/395.4MB +051e4ee23882: Loading layer [==================================================>] 9.216kB/9.216kB +6cca4437b6f6: Loading layer [==================================================>] 9.216kB/9.216kB +1d48fc08c8bc: Loading layer [==================================================>] 7.68kB/7.68kB +0419724fd942: Loading layer [==================================================>] 1.536kB/1.536kB +543c0c1ee18d: Loading layer [==================================================>] 655.2MB/655.2MB +4190aa7e89b8: Loading layer [==================================================>] 103.9kB/103.9kB +Loaded image: vmware/harbor-migrator:v1.5.0 + + +[Step 2]: preparing environment ... +Generated and saved secret to file: /data/secretkey +Generated configuration file: ./common/config/nginx/nginx.conf +Generated configuration file: ./common/config/adminserver/env +Generated configuration file: ./common/config/ui/env +Generated configuration file: ./common/config/registry/config.yml +Generated configuration file: ./common/config/db/env +Generated configuration file: ./common/config/jobservice/env +Generated configuration file: ./common/config/jobservice/config.yml +Generated configuration file: ./common/config/log/logrotate.conf +Generated configuration file: ./common/config/jobservice/config.yml +Generated configuration file: ./common/config/ui/app.conf +Generated certificate, key file: ./common/config/ui/private_key.pem, cert file: ./common/config/registry/root.crt +The configuration files are ready, please use docker-compose to start the service. +Creating harbor-log ... done + +[Step 3]: checking existing instance of Harbor ... + +Creating registry ... done +Creating harbor-ui ... done +Creating network "harbor_harbor" with the default driver +Creating nginx ... done +Creating registry ... +Creating harbor-adminserver ... +Creating harbor-db ... +Creating redis ... +Creating harbor-ui ... +Creating harbor-jobservice ... +Creating nginx ... + +✔ ----Harbor has been installed and started successfully.---- + +Now you should be able to visit the admin portal at http://harbor.gitnavi.com. +For more details, please visit https://github.com/vmware/harbor . +``` + +- 安装成功后,可以访问: + - 默认用户名:`admin` + - 默认密码:`Harbor12345` +- docker 客户端默认是使用 https 访问 docker registry,我们默认在安装 Harbor 的时候配置文件用的时候 http,所以其他 docker 客户端需要修改 + - `vim /lib/systemd/system/docker.service` + - 修改默认值为:`ExecStart=/usr/bin/dockerd` + - 改为:`ExecStart=/usr/bin/dockerd --insecure-registry harbor.gitnavi.com` + - `systemctl daemon-reload` + - `systemctl reload docker` + - `systemctl restart docker` +- 访问:,创建一个项目,比如:`youmeek`,等下需要用到。 + - 这里用 admin 用户,不再另外创建用了,但是实际使用最好新建用户。 + - `docker login -u admin -p Harbor12345 harbor.gitnavi.com` +- 给本地的一个 maven 镜像打 tag:`docker tag maven:3.3-jdk-8 harbor.gitnavi.com/youmeek/harbor-maven:3.3-jdk-8` +- push 到仓库:`docker push 182.61.19.178/demo/springboot-jenkins-docker:3` + +---------------------------------------------------------------------------- + +## harbor.cfg 默认值 + + +``` +## Configuration file of Harbor + +#This attribute is for migrator to detect the version of the .cfg file, DO NOT MODIFY! +_version = 1.5.0 +#The IP address or hostname to access admin UI and registry service. +#DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients. +hostname = reg.mydomain.com + +#The protocol for accessing the UI and token/notification service, by default it is http. +#It can be set to https if ssl is enabled on nginx. +ui_url_protocol = http + +#Maximum number of job workers in job service +max_job_workers = 50 + +#Determine whether or not to generate certificate for the registry's token. +#If the value is on, the prepare script creates new root cert and private key +#for generating token to access the registry. If the value is off the default key/cert will be used. +#This flag also controls the creation of the notary signer's cert. +customize_crt = on + +#The path of cert and key files for nginx, they are applied only the protocol is set to https +ssl_cert = /data/cert/server.crt +ssl_cert_key = /data/cert/server.key + +#The path of secretkey storage +secretkey_path = /data + +#Admiral's url, comment this attribute, or set its value to NA when Harbor is standalone +admiral_url = NA + +#Log files are rotated log_rotate_count times before being removed. If count is 0, old versions are removed rather than rotated. +log_rotate_count = 50 +#Log files are rotated only if they grow bigger than log_rotate_size bytes. If size is followed by k, the size is assumed to be in kilobytes. +#If the M is used, the size is in megabytes, and if G is used, the size is in gigabytes. So size 100, size 100k, size 100M and size 100G +#are all valid. +log_rotate_size = 200M + +#Config http proxy for Clair, e.g. http://my.proxy.com:3128 +#Clair doesn't need to connect to harbor ui container via http proxy. +http_proxy = +https_proxy = +no_proxy = 127.0.0.1,localhost,ui + +#NOTES: The properties between BEGIN INITIAL PROPERTIES and END INITIAL PROPERTIES +#only take effect in the first boot, the subsequent changes of these properties +#should be performed on web ui + +#************************BEGIN INITIAL PROPERTIES************************ + +#Email account settings for sending out password resetting emails. + +#Email server uses the given username and password to authenticate on TLS connections to host and act as identity. +#Identity left blank to act as username. +email_identity = + +email_server = smtp.mydomain.com +email_server_port = 25 +email_username = sample_admin@mydomain.com +email_password = abc +email_from = admin +email_ssl = false +email_insecure = false + +##The initial password of Harbor admin, only works for the first time when Harbor starts. +#It has no effect after the first launch of Harbor. +#Change the admin password from UI after launching Harbor. +harbor_admin_password = Harbor12345 + +##By default the auth mode is db_auth, i.e. the credentials are stored in a local database. +#Set it to ldap_auth if you want to verify a user's credentials against an LDAP server. +auth_mode = db_auth + +#The url for an ldap endpoint. +ldap_url = ldaps://ldap.mydomain.com + +#A user's DN who has the permission to search the LDAP/AD server. +#If your LDAP/AD server does not support anonymous search, you should configure this DN and ldap_search_pwd. +#ldap_searchdn = uid=searchuser,ou=people,dc=mydomain,dc=com + +#the password of the ldap_searchdn +#ldap_search_pwd = password + +#The base DN from which to look up a user in LDAP/AD +ldap_basedn = ou=people,dc=mydomain,dc=com + +#Search filter for LDAP/AD, make sure the syntax of the filter is correct. +#ldap_filter = (objectClass=person) + +# The attribute used in a search to match a user, it could be uid, cn, email, sAMAccountName or other attributes depending on your LDAP/AD +ldap_uid = uid + +#the scope to search for users, 0-LDAP_SCOPE_BASE, 1-LDAP_SCOPE_ONELEVEL, 2-LDAP_SCOPE_SUBTREE +ldap_scope = 2 + +#Timeout (in seconds) when connecting to an LDAP Server. The default value (and most reasonable) is 5 seconds. +ldap_timeout = 5 + +#Verify certificate from LDAP server +ldap_verify_cert = true + +#The base dn from which to lookup a group in LDAP/AD +ldap_group_basedn = ou=group,dc=mydomain,dc=com + +#filter to search LDAP/AD group +ldap_group_filter = objectclass=group + +#The attribute used to name a LDAP/AD group, it could be cn, name +ldap_group_gid = cn + +#The scope to search for ldap groups. 0-LDAP_SCOPE_BASE, 1-LDAP_SCOPE_ONELEVEL, 2-LDAP_SCOPE_SUBTREE +ldap_group_scope = 2 + +#Turn on or off the self-registration feature +self_registration = on + +#The expiration time (in minute) of token created by token service, default is 30 minutes +token_expiration = 30 + +#The flag to control what users have permission to create projects +#The default value "everyone" allows everyone to creates a project. +#Set to "adminonly" so that only admin user can create project. +project_creation_restriction = everyone + +#************************END INITIAL PROPERTIES************************ + +#######Harbor DB configuration section####### + +#The address of the Harbor database. Only need to change when using external db. +db_host = mysql + +#The password for the root user of Harbor DB. Change this before any production use. +db_password = root123 + +#The port of Harbor database host +db_port = 3306 + +#The user name of Harbor database +db_user = root + +##### End of Harbor DB configuration####### + +#The redis server address. Only needed in HA installation. +#address:port[,weight,password,db_index] +redis_url = redis:6379 + +##########Clair DB configuration############ + +#Clair DB host address. Only change it when using an exteral DB. +clair_db_host = postgres + +#The password of the Clair's postgres database. Only effective when Harbor is deployed with Clair. +#Please update it before deployment. Subsequent update will cause Clair's API server and Harbor unable to access Clair's database. +clair_db_password = password + +#Clair DB connect port +clair_db_port = 5432 + +#Clair DB username +clair_db_username = postgres + +#Clair default database +clair_db = postgres + +##########End of Clair DB configuration############ + +#The following attributes only need to be set when auth mode is uaa_auth +uaa_endpoint = uaa.mydomain.org +uaa_clientid = id +uaa_clientsecret = secret +uaa_verify_cert = true +uaa_ca_cert = /path/to/ca.pem + + +### Docker Registry setting ### +#registry_storage_provider can be: filesystem, s3, gcs, azure, etc. +registry_storage_provider_name = filesystem +#registry_storage_provider_config is a comma separated "key: value" pairs, e.g. "key1: value, key2: value2". +#Refer to https://docs.docker.com/registry/configuration/#storage for all available configuration. +registry_storage_provider_config = +``` + + +## 资料 + +- +- diff --git a/Hsk-Install.md b/markdown-file/Hsk-Install.md similarity index 100% rename from Hsk-Install.md rename to markdown-file/Hsk-Install.md diff --git a/markdown-file/Influxdb-Install-And-Settings.md b/markdown-file/Influxdb-Install-And-Settings.md new file mode 100644 index 00000000..82fe262d --- /dev/null +++ b/markdown-file/Influxdb-Install-And-Settings.md @@ -0,0 +1,70 @@ +# Influxdb 安装和配置 + + + +## Influxdb Docker 安装 + +- 官网库: + + +``` +docker run -d --name influxdb \ +-p 8086:8086 -p 8083:8083 \ +-e INFLUXDB_HTTP_AUTH_ENABLED=true \ +-e INFLUXDB_ADMIN_ENABLED=true -e INFLUXDB_ADMIN_USER=admin -e INFLUXDB_ADMIN_PASSWORD=123456 \ +-e INFLUXDB_DB=mydb1 \ +-v /Users/gitnavi/docker_data/influxdb/data:/var/lib/influxdb influxdb +``` + + +- 进入终端交互: + +``` +docker exec -it influxdb /bin/bash + +输入:influx,开始终端交互 + +auth admin 123456 +show databases; + +use springboot +show measurements + +show series from "jvm_buffer_total_capacity" + +select * from "jvm_buffer_total_capacity" + + +如果你要再额外创建数据库: +create database demo + +如果你要再创建用户: +create user "myuser" with password '123456' with all privileges +``` + + +---------------------------------------------------------------------------------------------- + +## 配置 + + + +---------------------------------------------------------------------------------------------- + + + +---------------------------------------------------------------------------------------------- + + +## 其他资料 + +- +- <> +- <> +- <> +- <> +- <> +- <> +- <> +- <> + diff --git a/Iptables.md b/markdown-file/Iptables.md similarity index 98% rename from Iptables.md rename to markdown-file/Iptables.md index d5925436..305a8b3b 100644 --- a/Iptables.md +++ b/markdown-file/Iptables.md @@ -21,7 +21,7 @@ iptables 的设置在 CentOS 和 Ubuntu 下有些细节不一样,Ubuntu 这里 - 常用命令: - 查看已有规则列表,并且显示编号:`iptables -L -n --line-numbers` - - ![Iptables 服务器配置文件常用参数](images/Iptables-a-1.jpg) + - ![Iptables 服务器配置文件常用参数](../images/Iptables-a-1.jpg) - 要删除 INPUT 里序号为 8 的规则,执行:`iptables -D INPUT 8` - 保存配置命令:`service iptables save 或者 /etc/rc.d/init.d/iptables save` - 重启服务命令 :`service iptables restart` diff --git a/JDK-Install.md b/markdown-file/JDK-Install.md similarity index 100% rename from JDK-Install.md rename to markdown-file/JDK-Install.md diff --git a/markdown-file/JMeter-Install-And-Settings.md b/markdown-file/JMeter-Install-And-Settings.md new file mode 100644 index 00000000..31946f33 --- /dev/null +++ b/markdown-file/JMeter-Install-And-Settings.md @@ -0,0 +1,185 @@ +# JMeter 安装和配置 + + +## JMeter 介绍 + +- JMeter 用 Java 开发,需要 JDK 环境,当前最新版至少需要 JDK 8 +- 官网: +- 官网下载: +- 官网插件库: +- 官网 Github 源码: +- 当前(201804)最新版本为 4.0 + +## JMeter Windows 安装 + +- 因为是绿色版本,直接解压即可,比如我解压后目录:`D:\software\portable\apache-jmeter-4.0\bin` +- 直接双击运行:`ApacheJMeter.jar`(会根据当前系统是中文自行进行切换语言) + - 也可以直接双击:`jmeter.bat`(显示的是英文版本) + - 如果是作为分布式中的客户端,需要执行:`jmeter-server.bat` +- 其他: + - `jmeter.log` 是 JMeter 的 log + - `jmeter.properties` 是 JMeter 软件配置 + +## JMeter Linux 安装 + +- 解压 zip 包,假设我放在 +- 增加环境变量:`vim ~/.zshrc`(我用的是 zsh) + +``` +# JMeter +JMETER_HOME=/usr/local/apache-jmeter-4.0 +PATH=$PATH:$JMETER_HOME/bin +export JMETER_HOME +export PATH +``` + +- 刷新配置:`source ~/.zshrc` +- 测试:`jmeter -v`,输出结果: + +``` +Apr 12, 2018 10:14:24 AM java.util.prefs.FileSystemPreferences$1 run +INFO: Created user preferences directory. + _ ____ _ ____ _ _ _____ _ __ __ _____ _____ _____ ____ + / \ | _ \ / \ / ___| | | | ____| | | \/ | ____|_ _| ____| _ \ + / _ \ | |_) / _ \| | | |_| | _| _ | | |\/| | _| | | | _| | |_) | + / ___ \| __/ ___ \ |___| _ | |___ | |_| | | | | |___ | | | |___| _ < +/_/ \_\_| /_/ \_\____|_| |_|_____| \___/|_| |_|_____| |_| |_____|_| \_\ 4.0 r1823414 + +Copyright (c) 1999-2018 The Apache Software Foundation +``` + +## JMeter Linux 测试 + +- Windows 是 GUI 操作,测试方便,Linux 只能用命令,所以这里进行记录 +- 准备好 jmx 测试脚本文件(可以在 Windows 上使用后,保存的脚本就是 jmx 后缀文件) +- 测试:`jmeter -n -t /opt/myTest.jmx -l /opt/myReport.jtl` + - 参数 n 表示以 nogui 方式运行测试计划 + - 参数 t 表示指定测试计划 + - 参数 l 表示生成测试报告 +- 显示 ... end of run 即脚本运行结束 +- 如果要后台运行 JMeter 可以:`setsid jmeter -n -t /opt/myTest.jmx -l /opt/myReport.jtl` +- 将上一步运行结束后生成的.jtl 文件拷贝到 win 上,打开 win 上的 Jmeter,随便新建一个项目,也可以用之前的项目,添加监听器,在监听器界面点击浏览,选择该.jtl 文件,就可以查看结果了 + + +## JMeter 分布式安装 + +- 分布式环境:分为 server、client + - server 等同于 controller、master(server 其实也可以作为 Client 使用,但是不推荐这样做) + - client 等同于 agent、slave +- **注意事项** + - 1、保持 controller 和 agent 机器的 JDK、jmeter 以及插件等配置版本一致; + - 2、如果测试数据有用到 CSV 或者其他方式进行参数化,需要将 data pools 在每台 Agent 上复制一份,且读取路径必须保持一致; + - 3、确保 controller 和 agent 机器在同一个子网里面; + - 4、检查防火墙是否被关闭,端口是否被占用(防火墙会影响脚本执行和测试结构收集,端口占用会导致 Agent 机报错); + - 5、分布式测试中,通过远程启动代理服务器,默认查看结果树中的响应数据为空,只有错误信息会被报回; + - 6、如果并发较高,建议将 controller 机设置为只启动测试脚本和收集汇总测试结果,在配置文件里去掉 controller 机的 IP; + - 7、分布式测试中,如果 1S 启动 100 个模拟请求,有 5 个 Agent 机,那么需要将脚本的线程数设置为 20,否则模拟请求数会变成 500,和预期结果相差太大。 +- 分布式测试流程: + - 运行所有 agent 机器上的 jmeter-server.bat 文件 + - 假定我们使用两台机器 192.168.0.1 和 192.168.0.2 作为 agent + - 修改 controller 机器的 JMeter /bin/jmeter.properties 文件 + +``` +默认值是: +remote_hosts=127.0.0.1 + +修改为: +remote_hosts=192.168.0.1:1099,192.168.0.2:1099 + +其中默认 RMI 端口是 1099,如果被占用,可以看 http://jmeter.apache.org/usermanual/remote-test.html 进行修改 +``` + +- 启动 Controller 机器上的 JMeter.bat,进入 Run -> Remote Start + + +## JMeter 基础知识 + +### 线程组 + +- Ramp-up Period(in seconds) + - 决定多长时间启动所有线程。如果使用 10 个线程,ramp-up period 是 100 秒,那么 JMeter 用 100 秒使所有 10 个线程启动并运行。每个线程会在上一个线程启动后 10 秒(100/10)启动。Ramp-up 需要要充足长以避免在启动测试时有一个太大的工作负载,并且要充足小以至于最后一个线程在第一个完成前启动。一般设置 ramp-up 等于线程数,有需求再根据该值进行调整。 + - 一般不要设置为 0,不然 JMeter 一启动就会发送大量请求,服务器可能瞬间过载,测试不出平时那种因为平均访问带来的高负载情况。 + - 估值方法:假设线程数为 100, 估计的点击率为每秒 10 次, 那么估计的理想 ramp-up period 就是 100/10 = 10 秒。每秒点击率需要自己获取系统数据,或是自己估值。 + + +### 定时器 + +- 默认情况下,Jmeter 线程在发送请求之间没有间歇。建议为线程组添加某种定时器,以便设定请求之间应该隔多长时间。如果测试人员不设定这种延迟,Jmeter 可能会在短时间内产生大量访问请求,导致服务器被大量请求所淹没。 +- 定时器会让作用域内的每一个采样器都在执行前等待一个固定时长。如果测试人员为线程组添加了多个定时器,那么 Jmeter 会将这些定时器的时长叠加起来,共同影响作用域范围内的采样器。定时器可以作为采样器或者逻辑控制器的子项,目的是只影响作用域内的采样器。 + +#### synchronized timer(时间集合点,主要用于模拟高并发测试) + +- 该定时器主要是为了阻塞线程,直到指定的线程数量到达后,再一起释放,可以瞬间产生很大的压力。 +- 假设这样的配置: + - Number of Simulated Users to Group By = 10 + - Timeout in milliseconds = 0 +- 该配置表示当用户(线程)数达到 10 的时候才开始测试。 +- 下面那个参数 0,表示达到 10 个用户就开始访问。如果填写 1000,则表示达到 10 用户后,延迟 1000 毫秒才开始访问。 + +#### Constant Throughput Timer(常数吞吐量定时器,主要用于预设好 QPS 场景下测试) + +- constant throughput timer 常数吞吐量定时器可以让 jmeter 以指定数字的吞吐量(即指定 tps,只是这里要求指定每分钟的执行数,而不是每秒)执行。吞吐量计算的范围可以为指定为当前线程、当前线程组、所有线程组,并且计算吞吐量的依据可以是最近一次线程的执行时延。 + + +### 聚合报告 + +- `Label`:每个 JMeter 的 element(例如 HTTP Request)都有一个 Name 属性,这里显示的就是 Name 属性的值 +- `Samples`:表示你这次测试中一共发出了多少个请求,如果模拟 10 个用户,每个用户迭代 10 次,那么这里显示 100 +- `Average`:平均响应时间——默认情况下是单个 Request 的平均响应时间,当使用了 Transaction Controller 时,也可以以 Transaction 为单位显示平均响应时间(单位是毫秒) +- `Median`:中位数,也就是 50% 用户的响应时间(单位是毫秒) +- `90% Line`:90% 用户的响应时间 +- `Note`:关于 50% 和 90% 并发用户数的含义,请参考下文 +- `http://www.cnblogs.com/jackei/archive/2006/11/11/557972.html +- `Min`:最小响应时间 +- `Max`:最大响应时间 +- `Error%`:本次测试中出现错误的请求的数量 / 请求的总数(怎么测试出整个系统的压力了? 如果 Error% 里面开始出现大量的错误,那就说明系统开始有瓶颈了,基本这时候就是最大压力节点,也就可以得到系统最大并发数是多少了。一般错误率不高于 1%,优秀的情况是不高于 0.01%)(若出现错误就要看服务端的日志,查找定位原因) +- `Throughput`:吞吐量——默认情况下表示每秒完成的请求数(Request per Second),当使用了 Transaction Controller 时,也可以表示类似 LoadRunner 的 Transaction per Second 数 +- `KB/Sec`:每秒从服务器端接收到的数据量,相当于 LoadRunner 中的 Throughput/Sec,主要看网络传输能力 + + +## 常见问题 + +- 个人经验: + - 对开发机中的项目测试:一般 100 线程,循环 10 次即可。 + - 对服务器上的小项目测试:一般 300 线程,循环 10 次即可。 + - 对服务器上的中大型项目测试:采用分布式测试,分别测试:300 ~ 5000 线程情况。 + - 假设好一点的机子设置 500 线程,一般的机子设置 300 线程。预计总 5000 线程需要 5 台好机子, 9 台一般机子。 + - 也可以通过修改 JVM 方式来调整每台机子性能上限,修改 /bin/jmeter 的合适值 +``` +: "${HEAP:="-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m"}" +``` + +- JMeter 即使加了 cookie manage 也没有保存 session 的,一个原因是:HTTP 请求默认值,中服务器 IP,只能填 IP 或是域名,一定不要在这里面在加上某个后缀地址,这样没办法保存的 session 的 +- 测试多用户的同时测试的效果,一种是用 jmeter 的 csv 功能,一种是复制几个脚本,每个脚本里面的登录信息不一样。或者是创建两个不同的线程组,每个线程组的登录信息不一样,然后每个线程组都有自己的 HTTP Cookie 管理器 +- 在压力测试过程中,要监控服务器情况,可以使用 [nmon 系统性能监控工具的使用](Nmon.md) + +## JMeter 资料 + +- 图文: + - [官网 User's Manual](http://jmeter.apache.org/usermanual/) + - [快速学习Jmeter性能测试工具](http://gitbook.cn/books/58de71a8be13fa66243873ef/index.html) + - [jmeter:菜鸟入门到进阶系列](http://www.cnblogs.com/imyalost/p/7062784.html) +- 国内视频教程: + - [JMeter 之 HTTP 协议接口性能测试 - 慕课网](https://www.imooc.com/learn/791) + - [接口测试基础之入门篇 - 慕课网](https://www.imooc.com/learn/738) + - [JMeter 性能测试进阶案例实战 - 慕课网](https://coding.imooc.com/class/142.html) + - [性能测试工具—Jmeter- 我要自学网](http://www.51zxw.net/list.aspx?page=2&cid=520) + - [jmeter 视频教学课程 - 小强](https://www.youtube.com/watch?v=zIiXpCBaBgQ&list=PL3rfV4zNE8CD-rAwlXlGXilN5QpkqDWox) +- 国外视频教程: + - [JMeter Beginner](https://www.youtube.com/playlist?list=PLhW3qG5bs-L-zox1h3eIL7CZh5zJmci4c) + - [JMeter Advanced](https://www.youtube.com/playlist?list=PLhW3qG5bs-L_Eosy1Nj1tKHC5jcBAVkPb) + + +## 资料 + +- +- +- +- +- +- +- +- +- +- + diff --git a/markdown-file/Java-bin.md b/markdown-file/Java-bin.md new file mode 100644 index 00000000..edee24b9 --- /dev/null +++ b/markdown-file/Java-bin.md @@ -0,0 +1,407 @@ +# Java bin 目录下的工具 + +## JVM 内存结构 + +- 参考资料:[JVM内存结构(基于JDK8)](https://blog.csdn.net/qq_34457118/article/details/81712293) + +#### 运行时数据区(JVM 规范) + +![image.png](https://upload-images.jianshu.io/upload_images/12159-f8cdb04243ea36e4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) + +- VM 栈(JVM 虚拟机栈) + - 是线程私有的,它的生命周期和线程相同。它描述的是 Java 方法执行的内存模式。 +- Java 堆区(Heap) + - 是 Java 虚拟机所管理的内存中最大的一块。是被所有线程共享的一块内存区域,在虚拟机启动时候创建。用于存放对象实例。 +- 方法区(Method Area) + - 也是各个线程共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 + - 虽然在 JVM 规范上是描述为堆的一个逻辑部分,但是它有一个别名:Non-Heap(非堆),独立于堆区之外的。JDK8 它是:Metaspace 区 + - Metaspace:主要存放:Class、Package、Method、Field、字节码、常量池、符号引用等等 + - 方法区里面有一个:运行时常量池(Run-Time Constant Pool),用于存放编译期生成的各种字面量和符号应用,在类加载后进入该池存放。 +- 本地方法栈(Native Method Stacks) + - 与虚拟机栈所发挥的作用类似,之间的区别: + - 虚拟机栈是为虚拟机执行 Java 方法(也就是字节码)服务 + - 本地方法栈是为了虚拟机使用到 Native 方法服务。 + +#### JDK8 真实内存结构(HotSpot) + +- HotSpot--Java HotSpot Performance Engine,是 Java 虚拟机的一个实现,目前是 Oracle 在维护和发布。 + +![image.png](https://upload-images.jianshu.io/upload_images/12159-045ea5a11000e8df.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) + +#### JDK8 HotSpot 的堆内存区域结构 + +![image.png](https://upload-images.jianshu.io/upload_images/12159-6a94044da388bb0e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) + +- 组成:Eden + Surviver(S0 + S1) + Old +- 对象生命周期:Eden > Surviver(S0 + S1) > Old +- Eden:该区域是最主要的刚创建的对象的内存分配区域,绝大多数对象都会被创建到这里(除了部分大对象通过内存担保机制创建到Old区域,默认大对象都是能够存活较长时间的),该区域的对象大部分都是短时间都会死亡的,故垃圾回收器针对该部分主要采用标记整理算法了回收该区域。 +- Surviver:该区域也是属于新生代的区域,该区域是将在Eden中未被清理的对象存放到该区域中,该区域分为两块区域,采用的是复制算法,每次只使用一块,Eden与Surviver区域的比例是8:1,是根据大量的业务运行总结出来的规律。 +- Old:该区域是属于老年代,一般能够在Surviver中没有被清除出去的对象才会进入到这块区域,该区域主要是采用标记清除算法。 +- 总结:java堆的垃圾回收是垃圾回收器最主要的光顾对象,整体采用分代收集的策略,对不同区域结合其特点采用不同的垃圾收集算法。我们在编程中也应该关注这一块区域,尽量不适用大对象,尽可能的创建局部对象,使用过后确定废弃不用的对象及时断开引用,尽量避免使用循环的对象引用(可达性分析也是比较消耗资源的)等等。 + +#### JVM内存区域的详解图 + +![image.png](https://upload-images.jianshu.io/upload_images/12159-deafd9588b74a2cf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) + +#### 更多这类文章 + +- [从实际案例聊聊Java应用的GC优化](https://tech.meituan.com/jvm_optimize.html) + + +------------------------------------------------------------- + +## 频繁GC问题或内存溢出排查流程 + +- 使用 `jps`,查看线程ID,假设 PID 为 12011 +- 使用 `jstat -gc PID 250 20`,查看gc情况,一般比较关注PERM区的情况,查看GC的增长情况。 +- 使用 `jstat -gccause PID`:额外输出上次GC原因 +- 使用 `jmap -dump:format=b,file=/opt/myHeapDumpFileName 12011`,生成堆转储文件 +- 使用 jhat 或者可视化工具(Eclipse Memory Analyzer 、IBM HeapAnalyzer)分析堆情况。 +- 结合代码解决内存溢出或泄露问题。 + +## 死锁问题 + +- 使用 `jps`查看线程ID,假设 PID 为 12011 +- 使用 `jstack 12011` 查看线程情况 + +------------------------------------------------------------------- + + +## jps + +- 显示当前所有 java 进程 pid 的命令 + +``` +16470 Jps +12011 Bootstrap +``` + +- `jps -v` 跟:`ps -ef|grep java` 主要输出内容一样 +- `12011` 是我这边的一个 java 应用的 pid,下面的其他命令都是自己与此应用进行分析的 + +------------------------------------------------------------------- + +## jstat(重要) + +- 显示进程中的类装载、内存、垃圾收集、JIT编译等运行数据。 +- 查看类加载信息:`jstat -class PID` + +#### 垃圾回收统计 + +- `jstat -gc PID 250 10`,每250毫秒查询一次,一共查询10次。 + +``` + S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT +34944.0 34944.0 1006.5 0.0 279616.0 235729.8 699072.0 12407.5 20736.0 20145.5 2560.0 2411.8 6 0.392 0 0.000 0.392 +34944.0 34944.0 1006.5 0.0 279616.0 235729.8 699072.0 12407.5 20736.0 20145.5 2560.0 2411.8 6 0.392 0 0.000 0.392 +34944.0 34944.0 1006.5 0.0 279616.0 235729.8 699072.0 12407.5 20736.0 20145.5 2560.0 2411.8 6 0.392 0 0.000 0.392 +34944.0 34944.0 1006.5 0.0 279616.0 235729.8 699072.0 12407.5 20736.0 20145.5 2560.0 2411.8 6 0.392 0 0.000 0.392 +34944.0 34944.0 1006.5 0.0 279616.0 235729.8 699072.0 12407.5 20736.0 20145.5 2560.0 2411.8 6 0.392 0 0.000 0.392 +34944.0 34944.0 1006.5 0.0 279616.0 235729.8 699072.0 12407.5 20736.0 20145.5 2560.0 2411.8 6 0.392 0 0.000 0.392 +34944.0 34944.0 1006.5 0.0 279616.0 235729.8 699072.0 12407.5 20736.0 20145.5 2560.0 2411.8 6 0.392 0 0.000 0.392 +34944.0 34944.0 1006.5 0.0 279616.0 235729.8 699072.0 12407.5 20736.0 20145.5 2560.0 2411.8 6 0.392 0 0.000 0.392 +34944.0 34944.0 1006.5 0.0 279616.0 235729.8 699072.0 12407.5 20736.0 20145.5 2560.0 2411.8 6 0.392 0 0.000 0.392 +34944.0 34944.0 1006.5 0.0 279616.0 235729.8 699072.0 12407.5 20736.0 20145.5 2560.0 2411.8 6 0.392 0 0.000 0.392 +``` + +- 列含义说明: + - **34944.0 表示 34M 大小,235729.8 表示 235M ** + - **SO + S1 + Eden = young 区** + -S0C 年轻代中第一个survivor(幸存区)的容量 (字节) + -S1C 年轻代中第二个survivor(幸存区)的容量 (字节) + -S0U 年轻代中第一个survivor(幸存区)目前已使用空间 (字节) (字母 U 表示 used) + -S1U 年轻代中第二个survivor(幸存区)目前已使用空间 (字节) (字母 U 表示 used) + -EC 年轻代中Eden(伊甸园)的容量 (字节) + -EU 年轻代中Eden(伊甸园)目前已使用空间 (字节) + - **OC + OU = old 区** + -OC Old代的容量 (字节) + -OU Old代目前已使用空间 (字节) + - **MC + MU = Metaspace 区** + - MC 方法区大小 + - MU 方法区使用大小 + - 其他 + - CCSC 压缩类空间大小 + - CCSU 压缩类空间使用大小 + - YGC 年轻代垃圾回收次数 + - YGCT 年轻代垃圾回收消耗时间 + - FGC 老年代垃圾回收次数 + - FGCT 老年代垃圾回收消耗时间 + - GCT 垃圾回收消耗总时间 + +#### 堆内存统计 + +- `jstat -gccapacity 12011 250 10`,查询进程 12011 VM内存中三代(young,old,perm)对象的使用和占用大小,每250毫秒查询一次,一共查询10次。 + +``` + NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC +349504.0 1398080.0 349504.0 34944.0 34944.0 279616.0 699072.0 2796224.0 699072.0 699072.0 0.0 1067008.0 20736.0 0.0 1048576.0 2560.0 6 0 +349504.0 1398080.0 349504.0 34944.0 34944.0 279616.0 699072.0 2796224.0 699072.0 699072.0 0.0 1067008.0 20736.0 0.0 1048576.0 2560.0 6 0 +349504.0 1398080.0 349504.0 34944.0 34944.0 279616.0 699072.0 2796224.0 699072.0 699072.0 0.0 1067008.0 20736.0 0.0 1048576.0 2560.0 6 0 +349504.0 1398080.0 349504.0 34944.0 34944.0 279616.0 699072.0 2796224.0 699072.0 699072.0 0.0 1067008.0 20736.0 0.0 1048576.0 2560.0 6 0 +349504.0 1398080.0 349504.0 34944.0 34944.0 279616.0 699072.0 2796224.0 699072.0 699072.0 0.0 1067008.0 20736.0 0.0 1048576.0 2560.0 6 0 +349504.0 1398080.0 349504.0 34944.0 34944.0 279616.0 699072.0 2796224.0 699072.0 699072.0 0.0 1067008.0 20736.0 0.0 1048576.0 2560.0 6 0 +349504.0 1398080.0 349504.0 34944.0 34944.0 279616.0 699072.0 2796224.0 699072.0 699072.0 0.0 1067008.0 20736.0 0.0 1048576.0 2560.0 6 0 +349504.0 1398080.0 349504.0 34944.0 34944.0 279616.0 699072.0 2796224.0 699072.0 699072.0 0.0 1067008.0 20736.0 0.0 1048576.0 2560.0 6 0 +349504.0 1398080.0 349504.0 34944.0 34944.0 279616.0 699072.0 2796224.0 699072.0 699072.0 0.0 1067008.0 20736.0 0.0 1048576.0 2560.0 6 0 +349504.0 1398080.0 349504.0 34944.0 34944.0 279616.0 699072.0 2796224.0 699072.0 699072.0 0.0 1067008.0 20736.0 0.0 1048576.0 2560.0 6 0 +``` + +- 列含义说明: + - NGCMN 年轻代(young)中初始化(最小)的大小(字节) + - NGCMX 年轻代(young)的最大容量 (字节) + - NGC 年轻代(young)中当前的容量 (字节) + - S0C 年轻代中第一个survivor(幸存区)的容量 (字节) + - S1C 年轻代中第二个survivor(幸存区)的容量 (字节) + - EC 年轻代中Eden(伊甸园)的容量 (字节) + - OGCMN old代中初始化(最小)的大小 (字节) + - OGCMX old代的最大容量(字节) + - OGC old代当前新生成的容量 (字节) + - OC Old代的容量 (字节) + - MCMN 最小元数据容量 + - MCMX 最大元数据容量 + - MC 当前元数据空间大小 + - CCSMN 最小压缩类空间大小 + - CCSMX 最大压缩类空间大小 + - CCSC 当前压缩类空间大小 + - YGC 年轻代gc次数,从应用程序启动到采样时年轻代中gc次数 + - FGC 老年代GC次数,从应用程序启动到采样时old代(全gc = Full gc次数)gc次数 +- 更多其他参数的使用可以看: + - [Java命令学习系列(四)——jstat](https://mp.weixin.qq.com/s?__biz=MzI3NzE0NjcwMg==&mid=402330276&idx=2&sn=58117de92512f83090d0a9de738eeacd&scene=21#wechat_redirect) + - [java高分局之jstat命令使用](https://blog.csdn.net/maosijunzi/article/details/46049117) + - [ jstat命令查看jvm的GC情况 (以Linux为例)](https://www.cnblogs.com/yjd_hycf_space/p/7755633.html) + +#### gcutil + +- 使用:`jstat -gcutil PID 3000 10`: +- 正常情况结果应该是这样的: + +``` +S0 S1 E O M CCS YGC YGCT FGC FGCT GCT +0.00 0.00 67.63 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.68 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.68 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.68 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.68 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.68 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.68 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.68 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.71 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.71 38.09 78.03 68.82 124 0.966 5 0.778 1.744 + +``` + +- S0:SO 当前使用比例 +- S1:S1 当前使用比例 +- E:**Eden 区使用比例(百分比)(异常的时候,这里可能会接近 100%)** +- O:**old 区使用比例(百分比)(异常的时候,这里可能会接近 100%)** +- M:**Metaspace 区使用比例(百分比)(异常的时候,这里可能会接近 100%)** +- CCS:压缩使用比例 +- YGC:年轻代垃圾回收次数 +- FGC:老年代垃圾回收次数 +- FGCT:老年代垃圾回收消耗时间(Full gc耗时)(单位秒) +- GCT:垃圾回收消耗总时间(单位秒) +- **异常的时候每次 Full GC 时间也可能非常长,每次时间计算公式=FGCT值/FGC指)** +- 在 YGC 之前 年轻代 = eden + S1;YGC 之后,年轻代 = eden + S0。 +- 如果看到 YGC 之后 old 区空间没变,表示此次 YGC,没有对象晋升到 old 区 + + + +------------------------------------------------------------------- + + +## jmap + +- 生成堆转储快照(heap dump) + - heap dump 主要记录了在某一时刻JVM堆中对象使用的情况,即某个时刻JVM堆的快照,是一个二进制文件,主要用于分析哪些对象占用了太对的堆空间,从而发现导致内存泄漏的对象。 +- 堆Dump是反应Java堆使用情况的内存镜像,其中主要包括系统信息、虚拟机属性、完整的线程Dump、所有类和对象的状态等。 一般,在内存不足、GC异常等情况下,我们就会怀疑有内存泄露。这个时候我们就可以制作堆Dump来查看具体情况,分析原因。 +- 常见内存错误: + - outOfMemoryError 年老代内存不足。 + - outOfMemoryError:PermGen Space 永久代内存不足。 + - outOfMemoryError:GC overhead limit exceed 垃圾回收时间占用系统运行时间的98%或以上。 +- `jmap -heap 12011`,查看指定进程堆(heap)使用情况 + +``` +Attaching to process ID 12011, please wait... +Debugger attached successfully. +Server compiler detected. +JVM version is 25.151-b12 + +using thread-local object allocation. +Mark Sweep Compact GC + +Heap Configuration: + MinHeapFreeRatio = 40 + MaxHeapFreeRatio = 70 + MaxHeapSize = 4294967296 (4096.0MB) + NewSize = 357892096 (341.3125MB) + MaxNewSize = 1431633920 (1365.3125MB) + OldSize = 715849728 (682.6875MB) + NewRatio = 2 + SurvivorRatio = 8 + MetaspaceSize = 21807104 (20.796875MB) + CompressedClassSpaceSize = 1073741824 (1024.0MB) + MaxMetaspaceSize = 17592186044415 MB + G1HeapRegionSize = 0 (0.0MB) + +Heap Usage: +New Generation (Eden + 1 Survivor Space): + capacity = 322109440 (307.1875MB) + used = 242418024 (231.1878433227539MB) + free = 79691416 (75.9996566772461MB) + 75.2595217327378% used +Eden Space: + capacity = 286326784 (273.0625MB) + used = 241387328 (230.20489501953125MB) + free = 44939456 (42.85760498046875MB) + 84.30483681191348% used +From Space: + capacity = 35782656 (34.125MB) + used = 1030696 (0.9829483032226562MB) + free = 34751960 (33.142051696777344MB) + 2.88043458819826% used +To Space: + capacity = 35782656 (34.125MB) + used = 0 (0.0MB) + free = 35782656 (34.125MB) + 0.0% used +tenured generation: + capacity = 715849728 (682.6875MB) + used = 12705280 (12.11669921875MB) + free = 703144448 (670.57080078125MB) + 1.774852947908084% used + +7067 interned Strings occupying 596016 bytes. +``` + + +- `jmap -histo 12011`,查看堆内存(histogram)中的对象数量及大小(下面 demo 内容太多,所以选取其中一部分) + - `jmap -histo:live 12011`,查看堆内存(histogram)中的对象数量及大小,但是JVM会先触发gc,然后再统计信息 + - `jmap -dump:format=b,file=/opt/myHeapDumpFileName 12011`,将内存使用的详细情况输出到文件,之后一般使用其他工具进行分析。 + - 生成的文件可以用一些可视化工具(Eclipse Memory Analyzer 、IBM HeapAnalyzer)来查看 + +``` +编号 个数 字节 类名 + 508: 6 192 java.lang.invoke.LambdaForm$BasicType + 509: 8 192 java.lang.invoke.MethodHandleImpl$Intrinsic + 510: 8 192 java.math.RoundingMode + 511: 6 192 java.net.NetworkInterface$1checkedAddresses + 512: 6 192 java.rmi.server.UID + 513: 3 192 java.text.DateFormatSymbols + 514: 8 192 java.util.Formatter$FixedString + 515: 6 192 java.util.TreeMap$KeyIterator + 516: 8 192 java.util.regex.Pattern$Slice + 517: 8 192 jdk.net.SocketFlow$Status + 518: 6 192 net.sf.ehcache.DefaultElementEvictionData + 519: 3 192 net.sf.ehcache.store.chm.SelectableConcurrentHashMap + 520: 8 192 org.apache.logging.log4j.Level + 521: 8 192 org.apache.logging.log4j.core.appender.rolling.RolloverFrequency + 522: 4 192 org.apache.logging.log4j.core.impl.ThrowableProxy + 523: 3 192 org.apache.logging.log4j.core.layout.PatternLayout + 524: 12 192 org.apache.logging.log4j.core.util.datetime.FastDateParser$NumberStrategy + 525: 3 192 org.apache.logging.log4j.core.util.datetime.FixedDateFormat + 526: 8 192 org.apache.logging.log4j.spi.StandardLevel + 527: 2 192 sun.nio.ch.ServerSocketChannelImpl + 528: 4 192 sun.nio.cs.StreamEncoder + 529: 6 192 sun.reflect.generics.reflectiveObjects.TypeVariableImpl + 530: 11 176 java.text.NumberFormat$Field + 531: 11 176 java.util.concurrent.ConcurrentSkipListSet + 532: 2 176 javax.management.remote.rmi.NoCallStackClassLoader + 533: 11 176 org.apache.logging.log4j.core.lookup.MapLookup + 534: 8 168 [Ljava.lang.reflect.TypeVariable; + 535: 1 168 [[Ljava.math.BigInteger; +``` + +------------------------------------------------------------------- + + +## jstack(线程快照 -- CPU 负载高) + +- jstack命令主要用来查看Java线程的调用堆栈的,可以用来分析线程问题(如死锁) +- jstack用于生成java虚拟机当前时刻的 **线程快照(thread dump)**。主要记录JVM在某一时刻各个线程执行的情况,以栈的形式显示,是一个文本文件。 +- 线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 + - 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。 + - 如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。 + - 另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。 +- `jstack 12011`,查看线程情况 +- `jstack -l 12011`,除堆栈外,显示关于锁的附件信息 +- 导出文件:`jstack -l PID >> /opt/jstack-tomcat1-20180917.log` + - 把占用 CPU 资源高的线程十进制的 PID 转换成 16 进制:`printf "%x\n" PID`,比如:`printf "%x\n" 12401` 得到结果是:`3071` + - 在刚刚输出的那个 log 文件中搜索:`3071`,可以找到:`nid=0x3071` +- 在线看某个线程 PID 的情况:`jstack 进程ID | grep 十六进制线程ID -A 10` + - `-A 10` 参数用来指定显示行数,否则只会显示一行信息 +- 下面 demo 内容太多,所以选取其中一部分结构: +- 常见线程状态 + - Runnable:正在运行的线程 + - Sleeping:休眠的线程 + - Waiting:等待的线程 + +``` +2018-03-08 14:28:13 +Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.151-b12 mixed mode): + +"Attach Listener" #53 daemon prio=9 os_prio=0 tid=0x00007f8a34009000 nid=0x865 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"Log4j2-AsyncLoggerConfig-1" #16 daemon prio=5 os_prio=0 tid=0x00007f8a5c48d800 nid=0x2f0c waiting on condition [0x00007f8a4cbfe000] + java.lang.Thread.State: WAITING (parking) + at sun.misc.Unsafe.park(Native Method) + - parking to wait for <0x00000007155e4850> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) + at com.lmax.disruptor.BlockingWaitStrategy.waitFor(BlockingWaitStrategy.java:45) + at com.lmax.disruptor.ProcessingSequenceBarrier.waitFor(ProcessingSequenceBarrier.java:56) + at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:124) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:748) + +"Wrapper-Control-Event-Monitor" #13 daemon prio=5 os_prio=0 tid=0x00007f8a5c34e000 nid=0x2efc waiting on condition [0x00007f8a60314000] + java.lang.Thread.State: TIMED_WAITING (sleeping) + at java.lang.Thread.sleep(Native Method) + at org.tanukisoftware.wrapper.WrapperManager$3.run(WrapperManager.java:731) + +"RMI TCP Accept-0" #11 daemon prio=5 os_prio=0 tid=0x00007f8a5c32f800 nid=0x2efa runnable [0x00007f8a60619000] + java.lang.Thread.State: RUNNABLE + at java.net.PlainSocketImpl.socketAccept(Native Method) + at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409) + at java.net.ServerSocket.implAccept(ServerSocket.java:545) + at java.net.ServerSocket.accept(ServerSocket.java:513) + at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:52) + at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:400) + at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:372) + at java.lang.Thread.run(Thread.java:748) + +"Service Thread" #7 daemon prio=9 os_prio=0 tid=0x00007f8a5c0b4800 nid=0x2ef3 runnable [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f8a5c0b1800 nid=0x2ef2 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f8a5c0af800 nid=0x2ef1 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f8a5c0aa800 nid=0x2ef0 runnable [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f8a5c07b000 nid=0x2eef in Object.wait() [0x00007f8a614f4000] + java.lang.Thread.State: WAITING (on object monitor) + at java.lang.Object.wait(Native Method) + - waiting on <0x00000007155e5ba8> (a java.lang.ref.ReferenceQueue$Lock) + at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) + - locked <0x00000007155e5ba8> (a java.lang.ref.ReferenceQueue$Lock) + at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) + at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209) + +"VM Thread" os_prio=0 tid=0x00007f8a5c06e800 nid=0x2eed runnable + +"VM Periodic Task Thread" os_prio=0 tid=0x00007f8a5c332000 nid=0x2efb waiting on condition + +JNI global references: 281 +``` + + +## 资料 + +- +- +- \ No newline at end of file diff --git a/markdown-file/Jenkins-Install-And-Settings.md b/markdown-file/Jenkins-Install-And-Settings.md new file mode 100644 index 00000000..a4101dea --- /dev/null +++ b/markdown-file/Jenkins-Install-And-Settings.md @@ -0,0 +1,961 @@ +# Jenkins 安装和配置 + +## Jenkins 介绍 + +- 官网: +- 官网插件库: +- 官网下载: +- 官网帮助中心: + +## Docker 下安装 Jenkins + +- 配置:至少需要 2G 内存 +- 先禁用 selinux + - 编辑配置文件:`vim /etc/selinux/config` + - 把 `SELINUX=enforcing` 改为 `SELINUX=disabled` + - 重启服务器 +- 官网下载中有介绍其版本标识: + - 我们就选用:Long-term Support (LTS) +- 官网关于 Docker 部署也有专门文档: +- 先创建一个宿主机以后用来存放数据的目录:`mkdir -p /data/jenkins/jenkins_home && chmod 777 -R /data/jenkins/jenkins_home` +- 安装镜像(813MB,有点大):`docker pull jenkins/jenkins:lts` +- 查看下载下来的镜像:`docker images` +- 首次运行镜像:`docker run --name jenkins-master -p 8123:18080 -p 50000:50000 -v /etc/localtime:/etc/localtime -v /data/jenkins/jenkins_home:/var/jenkins_home -e JAVA_OPTS="-Duser.timezone=Asia/Shanghai" -d --restart always jenkins/jenkins:lts` + - 这里的 8080 端口是 jenkins 运行程序的端口,必须要有映射的。50000 端口是非必须映射的,但是如果你要用 Jenkins 分布式构建这个就必须开放 +- 如果报下面的错误: + +``` +touch: cannot touch '/var/jenkins_home/copy_reference_file.log': Permission denied +Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions? +``` + +- 解决办法:`chown -R 1000:1000 /data/jenkins/jenkins_home`,具体原因:[点击查看](http://www.cnblogs.com/jackluo/p/5783116.html) + - 问题的本质就是,jenkins 镜像中的系统用户是:jenkins,当你进入容器 bash 内,输入:`whoami && id`,你就可以看到他的 uid 是 1000,所以这里才 chown 1000 +- 查看容器运行情况:`docker ps` +- 进入容器中 Jenkins shell 交互界面:`docker exec -it bd290d5eb0d /bin/bash` + +## 首次使用 Jenkins / Jenkins 插件推荐 + +- 我这里就不截图了,有需要截图可以看这博文,差不多就是这样的:[点击我o(∩_∩)o ](https://blog.csdn.net/boling_cavalry/article/details/78942408) +- 首次进入 Jenkins 的 Web UI 界面是一个解锁页面 Unlock Jenkins,需要让你输入:Administrator password + - 这个密码放在:`/var/jenkins_home/secrets/initialAdminPassword`,你需要先:`docker exec -it ci_jenkins_1 /bin/bash` + - 然后:`cat /data/jenkins/jenkins_home/secrets/initialAdminPassword` + - 也有可能是这个目录:`cat /var/jenkins_home/secrets/initialAdminPassword` +- 然后再接下来就是插件的安装,我推荐直接用它推荐给我们的插件直接安装,稍后再安装自己需要定制的。 +- 插件安装完会进入:Create First Admin User 页面,填写一个用户信息即可。 +- 我的这里的代码仓库是:Gitlab +- 推荐插件 + - Publish Over SSH(具体名字要看下) + - Dashbroad View + - Folders View + - OWASP Markup Formatter Plugin + - Build Name Setter Plugin + - build timeout plugin + - Credentials Binding Plugin + - Embeddable Build Status Plugin + - Pipeline + - Build Pipeline Plugin + - Docker Pipeline Plugin + - Git plugin + - GitLab Plugin + - SSH Slaves plugin + - Maven Integration plugin + - Matrix Authorization Strategy Plugin + - PAM Authentication plugin + - LDAP Plugin + - Role-based Authorization Strategy + - Email Extension Plugin + - Email Extension Template Plugin + - Mailer Plugin + - NotifyQQ([QQ 消息通知](https://github.com/ameizi/NotifyQQ)) + - 钉钉通知([钉钉 消息通知](https://wiki.jenkins.io/display/JENKINS/Dingding+Notification+Plugin)) + - 360 FireLine:代码规范检查,已经集成了阿里巴巴的代码规约(P3C)检查 + - AnsiColor(可选):这个插件可以让Jenkins的控制台输出的log带有颜色 + - oauth(具体名字要看下) + - Build Failure Analyzer 分析构建错误日志并在构建页面显示错误 + - SSH plugin 支持通过SSH执行脚本 + - Pre SCM BuildStep Plugin 在拉代码之前插入一些步骤 + - GitHub API Plugin Github API插件 + - GitHub Pull Request Builder Github Pull Request时自动构建 + - GitHub plugin Github与Jenkins集成 + - GIT client plugin Git客户端插件 + - Maven Integration plugin:用于构建 Maven 项目 + - Gradle Plugin:用于构建 Gradle 项目 + - Gitlab Plugin:可能会直接安装不成功,如果不成功根据报错的详细信息可以看到 hpi 文件的下载地址,挂代理下载下来,然后离线安装即可 + - Gitlab Hook:用于触发 GitLab 的一些 WebHooks 来构建项目 + - Gitlab Authentication 这个插件提供了使用GitLab进行用户认证和授权的方案 + - Docker Commons Plugin + - Docker plugin + - Kubernetes + - Pre SCM BuildStep Plugin 在拉代码之前插入一些步骤 + - GitHub Pull Request Builder Github Pull Request时自动构建 + - GitHub API Plugin Github API插件 + - NodeJS Plugin + + +## Docker 的 Jenkins 与 Docker 结合使用 + +- 运行镜像命令:`docker run --name jenkins-master -p 8123:18080 -p 50000:50000 -v /etc/localtime:/etc/localtime -v /data/jenkins/jenkins_home:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock -e JAVA_OPTS="-Duser.timezone=Asia/Shanghai" -d --restart always jenkins/jenkins:lts` + - 比上面多了一步:`-v /var/run/docker.sock:/var/run/docker.sock` +- 这样,在 jenkins 里面写 shell 脚本调用 docker 程序,就可以直接调用宿主机的 docker 了。 + +------------------------------------------------------------------- + +## Jenkins 安装(YUM) + +- **需要 JDK8 环境** +- 当前最新版本:`2.138.1-1.1`(201810) +- 官网安装说明 RedHat Linux RPM packages: +- 官网在线安装(72M),该安装方式会自己生成一个 jenkins 用户组和用户: + +``` +sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo +sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key + +sudo yum install -y jenkins +``` + +- 查看安装后的情况:`rpm -ql jenkins` + +``` +/etc/init.d/jenkins +/etc/logrotate.d/jenkins +/etc/sysconfig/jenkins +/usr/lib/jenkins +/usr/lib/jenkins/jenkins.war +/usr/sbin/rcjenkins +/var/cache/jenkins +/var/lib/jenkins +/var/log/jenkins +``` + +- jenkins 相关目录释义: + +``` +/usr/lib/jenkins/:jenkins安装目录,war 包会放在这里。 +/etc/sysconfig/jenkins:jenkins配置文件,“端口”,“JENKINS_HOME” 等都可以在这里配置。 +/var/lib/jenkins/:默认的 JENKINS_HOME。 +/var/log/jenkins/jenkins.log:jenkins 日志文件。 +``` + +- 控制台输出方式启动:`java -jar /usr/lib/jenkins/jenkins.war --httpPort=18080` +- 内置 Jetty,默认是 18080 端口,你也可以改为其他(建议修改为其他) +- 可以看到有一个这个重点内容,这是你的初始化密码,等下会用到的: + + +``` +Jenkins initial setup is required. An admin user has been created and a password generated. +Please use the following password to proceed to installation: + +daacc724767640a29ddc99d159a80cf8 + +This may also be found at: /root/.jenkins/secrets/initialAdminPassword +``` + +- 守护进程启动:`nohup java -jar /usr/lib/jenkins/jenkins.war --httpPort=18080 > /dev/null 2>&1 &` +- 浏览器访问 Jenkins 首页开始配置: +- 特殊情况: + - 如果配置插件过程遇到这个错误:`No valid crumb was included in the request`,则多重试几次。 + - 登录后把: 下面的 `防止跨站点请求伪造` 勾选去掉。遇到问题多试几次。 + + +## 忘记 admin 密码进行重置 + +- 备份配置文件:`cp /root/.jenkins/config.xml /root/.jenkins/config.xml.back` +- 编辑:`vim /root/.jenkins/config.xml`,删除 config.xml 文件中的这部分内容,在 10 行左右位置 + +``` +true + + true + + + true + false + +``` + +- 重启服务,进入首页此时系统是免密状态 +- 选择左侧的 `系统管理`,系统会提示你需要配置安全设置:`全局安全配置` + - 勾选 `启用安全` + - 安全域 > 勾选 `Jenkins专有用户数据库` + - 点击保存 +- 重新点击首页:`系统管理` + - 点击 `管理用户` + - 在用户列表中点击 admin 右侧齿轮 + - 修改密码,修改后即可重新登录。 +- 选择左侧的 `系统管理`,系统会提示你需要配置安全设置:`全局安全配置` + - 勾选 `启用安全` + - 授权策略 > 勾选 `登录用户可以做任何事` 或 `安全矩阵` + - 点击保存 + +------------------------------------------------------------------- + +## pipeline 语法 + +- 全局 pipeline 语法说明: +- 其他资料 + - + - + - + - + - + +#### 内置的参数 + +``` +BUILD_NUMBER = ${env.BUILD_NUMBER}" +BUILD_ID = ${env.BUILD_ID}" +BUILD_DISPLAY_NAME = ${env.BUILD_DISPLAY_NAME}" +JOB_NAME = ${env.JOB_NAME}" +JOB_BASE_NAME = ${env.JOB_BASE_NAME}" +WORKSPACE = ${env.WORKSPACE}" +JENKINS_HOME = ${env.JENKINS_HOME}" +JENKINS_URL = ${env.JENKINS_URL}" +BUILD_URL = ${env.BUILD_URL}" +JOB_URL = ${env.JOB_URL}" +``` + +- 输出结果: + +``` +BUILD_NUMBER = 21 +BUILD_ID = 21 +BUILD_DISPLAY_NAME = #21 +JOB_NAME = react +JOB_BASE_NAME = react +WORKSPACE = /root/.jenkins/workspace/react +JENKINS_HOME = /root/.jenkins +JENKINS_URL = http://192.168.0.105:18080/ +BUILD_URL = http://192.168.0.105:18080/job/react/21/ +JOB_URL = http://192.168.0.105:18080/job/react/ +``` + +#### 构建时指定参数 + +- 如果要构建的时候明确输入参数值,可以用 `parameters`: + +``` +pipeline { + agent any + + parameters { + string(name: 'assignVersionValue', defaultValue: '1.1.3', description: '构建之前请先指定版本号') + } + + tools { + jdk 'JDK8' + maven 'MAVEN3' + } + + options { + timestamps() + disableConcurrentBuilds() + buildDiscarder(logRotator( + numToKeepStr: '20', + daysToKeepStr: '30', + )) + } + + + environment { + gitUrl = "https://gitee.com/youmeek/springboot-jenkins-demo.git" + branchName = "master" + giteeCredentialsId = "Gitee" + projectWorkSpacePath = "${env.WORKSPACE}" + } + + + stages { + + stage('Check Env') { + + /*当指定的参数版本号等于空字符的时候进入 steps。这里的 when 对 当前 stage 有效,对其他 stage 无效*/ + when { + environment name: 'assignVersionValue', value: '' + } + + /*结束整个任务。如果不想结束整个任务,就不要用:exit 1*/ + steps { + sh "exit 1" + } + } + + stage('Pre Env') { + + steps { + echo "======================================项目名称 = ${env.JOB_NAME}" + echo "======================================项目 URL = ${gitUrl}" + echo "======================================项目分支 = ${branchName}" + echo "======================================当前编译版本号 = ${env.BUILD_NUMBER}" + echo "======================================项目空间文件夹路径 = ${projectWorkSpacePath}" + echo "======================================构建时自己指定的版本号值 = ${params.assignVersionValue}" + } + } + + } +} +``` + + +#### 定时构建 + +``` +pipeline { + agent any + + /*采用 linux cron 语法即可*/ + triggers { + cron('*/1 * * * *') + } + + tools { + jdk 'JDK8' + maven 'MAVEN3' + } + + options { + timestamps() + disableConcurrentBuilds() + buildDiscarder(logRotator( + numToKeepStr: '20', + daysToKeepStr: '30', + )) + } + + + environment { + gitUrl = "https://gitee.com/youmeek/springboot-jenkins-demo.git" + branchName = "master" + giteeCredentialsId = "Gitee" + projectWorkSpacePath = "${env.WORKSPACE}" + } + + + stages { + + stage('Pre Env') { + steps { + echo "======================================项目名称 = ${env.JOB_NAME}" + echo "======================================项目 URL = ${gitUrl}" + echo "======================================项目分支 = ${branchName}" + echo "======================================当前编译版本号 = ${env.BUILD_NUMBER}" + echo "======================================项目空间文件夹路径 = ${projectWorkSpacePath}" + } + } + + } +} + +``` + +#### 同时构建其他 Job + +``` +stage('运行其他任务') { + steps { + build job: '任务名称' + } +} +``` + + +------------------------------------------------------------------- + +## Jenkins 前端 React 项目构建 + +- **确保**:安装了 [Node.js](Node-Install-And-Usage.md) + +#### 简单的 pipeline 写法(开源项目) + +``` +pipeline { + agent any + + options { + timestamps() + disableConcurrentBuilds() + buildDiscarder(logRotator( + numToKeepStr: '20', + daysToKeepStr: '30', + )) + } + + /*=======================================常修改变量-start=======================================*/ + + environment { + gitUrl = "https://github.com/satan31415/heh_umi_template.git" + branchName = "master" + projectBuildPath = "${env.WORKSPACE}/dist" + nginxHtmlRoot = "/usr/share/nginx/react" + } + + /*=======================================常修改变量-end=======================================*/ + + stages { + + stage('Pre Env') { + steps { + echo "======================================项目名称 = ${env.JOB_NAME}" + echo "======================================项目 URL = ${gitUrl}" + echo "======================================项目分支 = ${branchName}" + echo "======================================当前编译版本号 = ${env.BUILD_NUMBER}" + echo "======================================项目 Build 文件夹路径 = ${projectBuildPath}" + echo "======================================项目 Nginx 的 ROOT 路径 = ${nginxHtmlRoot}" + } + } + + stage('Git Clone'){ + steps { + git branch: "${branchName}", url: "${gitUrl}" + } + } + + stage('NPM Install') { + steps { + sh "npm install" + } + } + + stage('NPM Build') { + steps { + sh "npm run build" + } + } + + stage('Nginx Deploy') { + steps { + sh "rm -rf ${nginxHtmlRoot}/" + sh "cp -r ${projectBuildPath}/ ${nginxHtmlRoot}/" + } + } + + + } +} +``` + + +#### 简单的 pipeline 写法(闭源项目 -- 码云为例) + +- 新增一个全局凭据: +- 类型:`Username with password` +- 范围:`全局` +- Username:`你的 Gitee 账号` +- Password:`你的 Gitee 密码` +- **ID**:`只要是唯一值就行,后面要用到` +- 描述:`最好跟 ID 一致,方便认` + +``` +pipeline { + agent any + + options { + timestamps() + disableConcurrentBuilds() + buildDiscarder(logRotator( + numToKeepStr: '20', + daysToKeepStr: '30', + )) + } + + /*=======================================常修改变量-start=======================================*/ + + environment { + gitUrl = "https://gitee.com/youmeek/react-demo.git" + branchName = "master" + giteeCredentialsId = "上面全局凭据填写的 ID" + projectBuildPath = "${env.WORKSPACE}/dist" + nginxHtmlRoot = "/usr/share/nginx/react" + } + + /*=======================================常修改变量-end=======================================*/ + + stages { + + stage('Pre Env') { + steps { + echo "======================================项目名称 = ${env.JOB_NAME}" + echo "======================================项目 URL = ${gitUrl}" + echo "======================================项目分支 = ${branchName}" + echo "======================================当前编译版本号 = ${env.BUILD_NUMBER}" + echo "======================================项目 Build 文件夹路径 = ${projectBuildPath}" + echo "======================================项目 Nginx 的 ROOT 路径 = ${nginxHtmlRoot}" + } + } + + stage('Git Clone'){ + steps { + git branch: "${branchName}", + credentialsId: "${giteeCredentialsId}", + url: "${gitUrl}" + } + } + + stage('NPM Install') { + steps { + sh "npm install" + } + } + + stage('NPM Build') { + steps { + sh "npm run build" + } + } + + stage('Nginx Deploy') { + steps { + sh "rm -rf ${nginxHtmlRoot}/" + sh "cp -r ${projectBuildPath}/ ${nginxHtmlRoot}/" + } + } + + + } +} +``` + + +------------------------------------------------------------------- + +## Jenkins 后端 Spring Boot 项目构建 + +#### 安装 Maven + +- [参考该文章](Maven-Install-And-Settings.md) + +#### 配置工具 + +- 访问: +- 我习惯自己安装,所以这里修改配置: + - **需要注意**:配置里面的 `别名` 不要随便取名字,后面 Pipeline 要用到的。在 tool 标签里面会用到。 + - 具体可以查看该图片说明:[点击查看](https://upload-images.jianshu.io/upload_images/12159-ef61595aebaa4244.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) + + +#### 简单的 pipeline 写法(Jar 方式运行)(闭源项目 -- 码云为例) + +###### 用 supervisord 做进程控制 + +- [supervisord 的使用](Daemontools.md) +- 生成 supervisord 的配置文件会写在 Pipeline,所以只要你保证服务器 supervisord 正常运行即可 + +###### 配置 Jenkins + +- **必须**:新增一个全局凭据,方法参考前端部分 + +``` +pipeline { + agent any + + /*=======================================工具环境修改-start=======================================*/ + tools { + jdk 'JDK8' + maven 'MAVEN3' + } + /*=======================================工具环境修改-end=======================================*/ + + options { + timestamps() + disableConcurrentBuilds() + buildDiscarder(logRotator( + numToKeepStr: '20', + daysToKeepStr: '30', + )) + } + + /*=======================================常修改变量-start=======================================*/ + + environment { + gitUrl = "https://gitee.com/youmeek/springboot-jenkins-demo.git" + branchName = "master" + giteeCredentialsId = "Gitee" + projectWorkSpacePath = "${env.WORKSPACE}" + projectBuildTargetPath = "${env.WORKSPACE}/target" + projectJarNewName = "${env.JOB_NAME}.jar" + supervisorConfigFileFullPath = "/etc/supervisor/conf.d/${env.JOB_NAME}.conf" + supervisorLogPath = "/var/log/supervisor" + + } + + /*=======================================常修改变量-end=======================================*/ + + stages { + + stage('Pre Env') { + steps { + echo "======================================项目名称 = ${env.JOB_NAME}" + echo "======================================项目 URL = ${gitUrl}" + echo "======================================项目分支 = ${branchName}" + echo "======================================当前编译版本号 = ${env.BUILD_NUMBER}" + echo "======================================项目空间文件夹路径 = ${projectWorkSpacePath}" + echo "======================================项目 build 后 jar 路径 = ${projectBuildTargetPath}" + echo "======================================项目 jar 新名称 = ${projectJarNewName}" + echo "======================================supervisor 配置文件路径 = ${supervisorConfigFileFullPath}" + echo "======================================supervisor 存放 log 路径 = ${supervisorLogPath}" + } + } + + stage('Git Clone'){ + steps { + git branch: "${branchName}", + credentialsId: "${giteeCredentialsId}", + url: "${gitUrl}" + } + } + + stage('Maven Clean') { + steps { + sh "mvn clean" + } + } + + stage('Maven Package') { + steps { + sh "mvn package -DskipTests" + } + } + + stage('Spring Boot Run') { + steps { + +sh """ +mv ${projectBuildTargetPath}/*.jar ${projectBuildTargetPath}/${projectJarNewName} + +if [ ! -f ${supervisorConfigFileFullPath} ]; then + +touch ${supervisorConfigFileFullPath} + +cat << EOF >> ${supervisorConfigFileFullPath} +[program:${env.JOB_NAME}] +command=java -jar ${projectBuildTargetPath}/${projectJarNewName} +stdout_logfile=${supervisorLogPath}/${env.JOB_NAME}.log +stderr_logfile=${supervisorLogPath}/${env.JOB_NAME}-err.log +user=root +autostart=true +autorestart=false +startsecs=5 +priority=1 +stopasgroup=true +killasgroup=true +EOF + +/usr/bin/supervisorctl update +fi + +/usr/bin/supervisorctl restart ${env.JOB_NAME} +""" + + } + } + + } +} +``` + + + +#### 简单的 pipeline 写法(Docker 方式运行)(闭源项目 -- 码云为例) + +- **确保** 项目根目录有 Dockerfile 文件(部分内容自己修改),内容模板: + +``` +FROM java:8 +VOLUME /tmp + +ENV TZ=Asia/Shanghai +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +ADD ./target/buildApp.jar /app.jar + +RUN bash -c 'touch /app.jar' + +EXPOSE 8081 + +ENTRYPOINT ["java", "-jar", "-Xms512M", "-Xmx512M" , "-XX:MetaspaceSize=128M", "-XX:MaxMetaspaceSize=256M" ,"/app.jar"] +``` + +- Pipeline 写法 + +``` +pipeline { + agent any + + /*=======================================工具环境修改-start=======================================*/ + tools { + jdk 'JDK8' + maven 'MAVEN3' + } + /*=======================================工具环境修改-end=======================================*/ + + options { + timestamps() + disableConcurrentBuilds() + buildDiscarder(logRotator( + numToKeepStr: '20', + daysToKeepStr: '30', + )) + } + + /*=======================================常修改变量-start=======================================*/ + + environment { + gitUrl = "https://gitee.com/youmeek/springboot-jenkins-demo.git" + branchName = "master" + giteeCredentialsId = "Gitee" + projectWorkSpacePath = "${env.WORKSPACE}" + projectBuildTargetPath = "${env.WORKSPACE}/target" + projectJarNewName = "buildApp.jar" + + + dockerImageName = "docker.youmeek.com/demo/${env.JOB_NAME}:${env.BUILD_NUMBER}" + dockerContainerName = "${env.JOB_NAME}" + inHostPort = "8082" + inDockerAndJavaPort = "8081" + inHostLogPath = "/data/docker/logs/${dockerContainerName}/${env.BUILD_NUMBER}" + inDockerLogPath = "/data/logs" + dockerRunParam = "--name=${dockerContainerName} --hostname=${dockerContainerName} -v /etc/hosts:/etc/hosts -v ${inHostLogPath}:${inDockerLogPath} --restart=always -p ${inHostPort}:${inDockerAndJavaPort}" + } + + /*=======================================常修改变量-end=======================================*/ + + stages { + + stage('Pre Env') { + steps { + echo "======================================项目名称 = ${env.JOB_NAME}" + echo "======================================项目 URL = ${gitUrl}" + echo "======================================项目分支 = ${branchName}" + echo "======================================当前编译版本号 = ${env.BUILD_NUMBER}" + echo "======================================项目空间文件夹路径 = ${projectWorkSpacePath}" + echo "======================================项目 build 后 jar 路径 = ${projectBuildTargetPath}" + echo "======================================项目 jar 新名称 = ${projectJarNewName}" + echo "======================================Docker 镜像名称 = ${dockerImageName}" + echo "======================================Docker 容器名称 = ${dockerContainerName}" + } + } + + stage('Git Clone'){ + steps { + git branch: "${branchName}", + credentialsId: "${giteeCredentialsId}", + url: "${gitUrl}" + } + } + + stage('Maven Clean') { + steps { + sh "mvn clean" + } + } + + stage('Maven Package') { + steps { + sh "mvn package -DskipTests" + } + } + + stage('构建 Docker 镜像') { + steps { + sh """ + mv ${projectBuildTargetPath}/*.jar ${projectBuildTargetPath}/${projectJarNewName} + + cd ${projectWorkSpacePath} + + docker build -t ${dockerImageName} ./ + """ + } + } + + stage('运行 Docker 镜像') { + steps { + sh """ + docker stop ${dockerContainerName} | true + + docker rm -f ${dockerContainerName} | true + + docker run -d ${dockerRunParam} ${dockerImageName} + """ + } + } + + + + + + + } +} +``` + + +#### 简单的 pipeline 写法(Docker + Harbor 方式运行)(闭源项目 -- 码云为例) + +- 请先看懂上面 Docker 方式 +- 一共需要 3 台机子(要保证在内网环境,不然一定会有安全问题) + - 一台部署 [Harbor](Harbor-Install-And-Usage.md) + - 一台部署 Jenkins + - 一台运行项目 +- 确保 Jenkins 机子已经 Docker Login Harbor,这个就一次性的动作,所以自己在 Jenkins 服务器上操作即可 +- 确保 Spring Boot 项目运行的机子已经 Docker Login Harbor,这个就一次性的动作,所以自己在 Jenkins 服务器上操作即可 +- 确保 Spring Boot 项目运行的机子 docker remote api 开启(没有身份认证功能,所以才要保证内网) +- Pipeline 写法 + +``` +pipeline { + agent any + + /*=======================================工具环境修改-start=======================================*/ + tools { + jdk 'JDK8' + maven 'MAVEN3' + } + /*=======================================工具环境修改-end=======================================*/ + + options { + timestamps() + disableConcurrentBuilds() + buildDiscarder(logRotator( + numToKeepStr: '20', + daysToKeepStr: '30', + )) + } + + /*=======================================常修改变量-start=======================================*/ + + environment { + gitUrl = "https://gitee.com/youmeek/springboot-jenkins-demo.git" + branchName = "master" + giteeCredentialsId = "Gitee" + projectWorkSpacePath = "${env.WORKSPACE}" + projectBuildTargetPath = "${env.WORKSPACE}/target" + projectJarNewName = "buildApp.jar" + + projectDockerDaemon = "tcp://192.168.1.12:2376" + harborUrl = "192.168.1.13" + harborProjectName = "demo" + dockerImageName = "${harborUrl}/${harborProjectName}/${env.JOB_NAME}:${env.BUILD_NUMBER}" + dockerContainerName = "${env.JOB_NAME}" + inHostPort = "8082" + inDockerAndJavaPort = "8081" + inHostLogPath = "/data/docker/logs/${dockerContainerName}/${env.BUILD_NUMBER}" + inDockerLogPath = "/data/logs" + dockerRunParam = "--name=${dockerContainerName} --hostname=${dockerContainerName} -v /etc/hosts:/etc/hosts -v ${inHostLogPath}:${inDockerLogPath} --restart=always -p ${inHostPort}:${inDockerAndJavaPort}" + } + + /*=======================================常修改变量-end=======================================*/ + + stages { + + stage('Pre Env') { + steps { + echo "======================================项目名称 = ${env.JOB_NAME}" + echo "======================================项目 URL = ${gitUrl}" + echo "======================================项目分支 = ${branchName}" + echo "======================================当前编译版本号 = ${env.BUILD_NUMBER}" + echo "======================================项目空间文件夹路径 = ${projectWorkSpacePath}" + echo "======================================项目 build 后 jar 路径 = ${projectBuildTargetPath}" + echo "======================================项目 jar 新名称 = ${projectJarNewName}" + echo "======================================Docker 镜像名称 = ${dockerImageName}" + echo "======================================Docker 容器名称 = ${dockerContainerName}" + echo "======================================harbor 地址 = ${harborUrl}" + echo "======================================harbor 项目名称 = ${harborProjectName}" + echo "======================================项目在宿主机的端口 = ${inHostPort}" + echo "======================================项目在 Docker 容器中的端口 = ${inDockerAndJavaPort}" + echo "======================================项目在宿主机的 log 路径 = ${inHostLogPath}" + echo "======================================项目在 docker 容器的 log 路径 = ${inDockerLogPath}" + echo "======================================项目运行的 Docker remote ip 信息 = ${projectDockerDaemon}" + echo "======================================项目运行的参数 = ${dockerRunParam}" + } + } + + stage('Git Clone'){ + steps { + git branch: "${branchName}", + credentialsId: "${giteeCredentialsId}", + url: "${gitUrl}" + } + } + + stage('Maven Clean') { + steps { + sh "mvn clean" + } + } + + stage('Maven Package') { + steps { + sh "mvn package -DskipTests" + } + } + + stage('构建 Docker 镜像') { + steps { + sh """ + mv ${projectBuildTargetPath}/*.jar ${projectBuildTargetPath}/${projectJarNewName} + + cd ${projectWorkSpacePath} + + docker build -t ${dockerImageName} ./ + """ + } + } + + stage('Push Docker 镜像') { + options { + timeout(time: 5, unit: 'MINUTES') + } + steps { + sh """ + docker push ${dockerImageName} + docker rmi ${dockerImageName} + """ + } + } + + stage('运行远程 Docker 镜像') { + options { + timeout(time: 5, unit: 'MINUTES') + } + steps { + sh """ + docker -H ${projectDockerDaemon} pull ${dockerImageName} + + docker -H ${projectDockerDaemon} stop ${dockerContainerName} | true + + docker -H ${projectDockerDaemon} rm -f ${dockerContainerName} | true + + docker -H ${projectDockerDaemon} run -d ${dockerRunParam} ${dockerImageName} + """ + } + } + + + + + + + } +} +``` + + + + + +------------------------------------------------------------------- + +## 多节点 master 与 slave + +- 可以参考这篇: + + +------------------------------------------------------------------- + + +## 资料 + +- +- +- +- \ No newline at end of file diff --git a/markdown-file/Jira-Install-And-Settings.md b/markdown-file/Jira-Install-And-Settings.md new file mode 100644 index 00000000..b831ae36 --- /dev/null +++ b/markdown-file/Jira-Install-And-Settings.md @@ -0,0 +1,82 @@ +# Jira 安装和配置 + +## Jira 7.13.3 + +- 最新 7.13.3 版本时间:2019-04 + +#### 数据库 + +``` +docker run \ + --name mysql-jira \ + --restart always \ + -p 3306:3306 \ + -e MYSQL_ROOT_PASSWORD=adg123456 \ + -e MYSQL_DATABASE=jira_db \ + -e MYSQL_USER=jira_user \ + -e MYSQL_PASSWORD=jira_123456 \ + -d \ + mysql:5.7 +``` + +- 连上容器:`docker exec -it mysql-jira /bin/bash` + - 连上 MySQL:`mysql -u root -p` +- 设置编码:**必须做这一步,不然配置过程会报错,JIRA 的 DB 要求是 utf8mb4** + +``` +SET NAMES 'utf8mb4'; +alter database jira_db character set utf8mb4; +``` + + +#### 安装 + +- 下载: + - 选择:tar.gz 类型下载 +- 解压:`tar zxvf atlassian-jira-software-7.13.3.tar.gz` +- 创建 home 目录:`mkdir /usr/local/atlassian-jira-software-7.13.3-standalone/data` +- 配置 home 变量: + +``` +编辑:vim ~/.zshrc + +在文件尾部添加: + +JIRA_HOME=/usr/local/atlassian-jira-software-7.13.3-standalone/data +export JIRA_HOME + + +刷新配置:`source ~/.zshrc` +``` + +- 设置 MySQL 连接: +- 把 mysql-connector-java-5.1.47.jar 放在目录 `/usr/local/atlassian-jira-software-7.13.3-standalone/atlassian-jira/WEB-INF/lib` + + +#### License 过程 + +- 参考自己的为知笔记 + +#### 运行 + +- 启动:`sh /usr/local/atlassian-jira-software-7.13.3-standalone/bin/start-jira.sh` +- 停止:`sh /usr/local/atlassian-jira-software-7.13.3-standalone/bin/stop-jira.sh` + - `ps -ef | grep java` +- 查看 log:`tail -300f /usr/local/atlassian-jira-software-7.13.3-standalone/logs/catalina.out` +- 访问: + - 注意防火墙配置 +- 如果需要更换端口号可以修改:`/usr/local/atlassian-jira-software-7.13.3-standalone/conf/server.xml` 文件中的内容。 + + +#### 中文化 + +- 从 7.x 版本默认已经有中文支持,不需要再汉化了 +- 在安装后首次进入的时候就可以配置,选择中文了 + + +#### 首次配置 + +- 参考文章: +- 因为步骤一样,所以我就不再截图了。 + + diff --git a/markdown-file/K8S-Install-And-Usage.md b/markdown-file/K8S-Install-And-Usage.md new file mode 100644 index 00000000..bd14fb1d --- /dev/null +++ b/markdown-file/K8S-Install-And-Usage.md @@ -0,0 +1,536 @@ + + +# Kubernets(K8S) 使用 + +## 环境说明 + +- CentOS 7.5(不准确地说:要求必须是 CentOS 7 64位) +- Docker + +## Kubernetes + +- 目前流行的容器编排系统 +- 简称:K8S +- 官网: +- 主要解决几个问题: + - `调度` + - `生命周期及健康状况` + - `服务发现` + - `监控` + - `认证` + - `容器聚合` +- 主要角色:Master、Node + + +#### 安装准备 - Kubernetes 1.13 版本 + +- 推荐最低 2C2G,优先:2C4G 或以上 +- 特别说明:1.13 之前的版本,由于网络问题,需要各种设置,这里就不再多说了。1.13 之后相对就简单了点。 +- 优先官网软件包:kubeadm +- 官网资料: + - issues 入口: + - 源码入口: + - 安装指导: + - 按官网要求做下检查: + - 网络环境: + - 端口检查: + - **对 Docker 版本的支持,这里官网推荐的是 18.06**: +- 三大核心工具包,都需要各自安装,并且注意版本关系: + - `kubeadm`: the command to bootstrap the cluster. + - 集群部署、管理工具 + - `kubelet`: the component that runs on all of the machines in your cluster and does things like starting pods and containers. + - 具体执行层面的管理 Pod 和 Docker 工具 + - `kubectl`: the command line util to talk to your cluster. + - 操作 k8s 的命令行入口工具 +- 官网插件安装过程的故障排查: +- 其他部署方案: + - + - + - + +#### 开始安装 - Kubernetes 1.13.3 版本 + +- 三台机子: + - master-1:`192.168.0.127` + - node-1:`192.168.0.128` + - node-2:`192.168.0.129` +- 官网最新版本: +- 官网 1.13 版本的 changelog: +- **所有节点安装 Docker 18.06,并设置阿里云源** + - 可以参考:[点击我o(∩_∩)o ](https://github.com/judasn/Linux-Tutorial/blob/master/favorite-file/shell/install_docker_k8s_disable_firewalld_centos7-aliyun.sh) + - 核心,查看可以安装的 Docker 列表:`yum list docker-ce --showduplicates` +- 所有节点设置 kubernetes repo 源,并安装 Kubeadm、Kubelet、Kubectl 都设置阿里云的源 +- Kubeadm 初始化集群过程当中,它会下载很多的镜像,默认也是去 Google 家里下载。但是 1.13 新增了一个配置:`--image-repository` 算是救了命。 + +#### 安装具体流程 + +- 同步所有机子时间:`systemctl start chronyd.service && systemctl enable chronyd.service` +- 所有机子禁用防火墙、selinux、swap + +``` +systemctl stop firewalld.service +systemctl disable firewalld.service +systemctl disable iptables.service + +iptables -P FORWARD ACCEPT + +setenforce 0 && sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config + +echo "vm.swappiness = 0" >> /etc/sysctl.conf +swapoff -a && sysctl -w vm.swappiness=0 +``` + + +- 给各自机子设置 hostname 和 hosts + +``` +hostnamectl --static set-hostname k8s-master-1 +hostnamectl --static set-hostname k8s-node-1 +hostnamectl --static set-hostname k8s-node-2 + + +vim /etc/hosts +192.168.0.127 k8s-master-1 +192.168.0.128 k8s-node-1 +192.168.0.129 k8s-node-2 +``` + +- 给 master 设置免密 + +``` +ssh-keygen -t rsa + +cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys + + +ssh localhost + +ssh-copy-id -i ~/.ssh/id_rsa.pub -p 22 root@k8s-node-1(根据提示输入 k8s-node-1 密码) +ssh-copy-id -i ~/.ssh/id_rsa.pub -p 22 root@k8s-node-2(根据提示输入 k8s-node-2 密码) + +ssh k8s-master-1 +ssh k8s-node-1 +ssh k8s-node-2 +``` + + +- 给所有机子设置 yum 源 + +``` +vim /etc/yum.repos.d/kubernetes.repo + +[kubernetes] +name=Kubernetes +baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ +enabled=1 +gpgcheck=1 +repo_gpgcheck=1 +gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg + + +scp -r /etc/yum.repos.d/kubernetes.repo root@k8s-node-1:/etc/yum.repos.d/ +scp -r /etc/yum.repos.d/kubernetes.repo root@k8s-node-2:/etc/yum.repos.d/ +``` + +- 给 master 机子创建 flannel 配置文件 + +``` +mkdir -p /etc/cni/net.d && vim /etc/cni/net.d/10-flannel.conflist + +{ + "name": "cbr0", + "plugins": [ + { + "type": "flannel", + "delegate": { + "hairpinMode": true, + "isDefaultGateway": true + } + }, + { + "type": "portmap", + "capabilities": { + "portMappings": true + } + } + ] +} +``` + + + +- 给所有机子创建配置 + +``` +vim /etc/sysctl.d/k8s.conf + +net.bridge.bridge-nf-call-ip6tables = 1 +net.bridge.bridge-nf-call-iptables = 1 +net.ipv4.ip_forward=1 +vm.swappiness=0 + + +scp -r /etc/sysctl.d/k8s.conf root@k8s-node-1:/etc/sysctl.d/ +scp -r /etc/sysctl.d/k8s.conf root@k8s-node-2:/etc/sysctl.d/ + +modprobe br_netfilter && sysctl -p /etc/sysctl.d/k8s.conf +``` + +- 给所有机子安装组件 + +``` +yum install -y kubelet-1.13.3 kubeadm-1.13.3 kubectl-1.13.3 --disableexcludes=kubernetes +``` + +- 给所有机子添加一个变量 + +``` +vim /etc/systemd/system/kubelet.service.d/10-kubeadm.conf + +最后一行添加:Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs" +``` + + +- 启动所有机子 + +``` +systemctl enable kubelet && systemctl start kubelet + +kubeadm version +kubectl version + +``` + +- 初始化 master 节点: + +``` +echo 1 > /proc/sys/net/ipv4/ip_forward + + +kubeadm init \ +--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \ +--pod-network-cidr 10.244.0.0/16 \ +--kubernetes-version 1.13.3 \ +--ignore-preflight-errors=Swap + +其中 10.244.0.0/16 是 flannel 插件固定使用的ip段,它的值取决于你准备安装哪个网络插件 + +这个过程会下载一些 docker 镜像,时间可能会比较久,看你网络情况。 +终端会输出核心内容: +[init] Using Kubernetes version: v1.13.3 +[preflight] Running pre-flight checks +[preflight] Pulling images required for setting up a Kubernetes cluster +[preflight] This might take a minute or two, depending on the speed of your internet connection +[preflight] You can also perform this action in beforehand using 'kubeadm config images pull' +[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env" +[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" +[kubelet-start] Activating the kubelet service +[certs] Using certificateDir folder "/etc/kubernetes/pki" +[certs] Generating "front-proxy-ca" certificate and key +[certs] Generating "front-proxy-client" certificate and key +[certs] Generating "etcd/ca" certificate and key +[certs] Generating "etcd/server" certificate and key +[certs] etcd/server serving cert is signed for DNS names [k8s-master-1 localhost] and IPs [192.168.0.127 127.0.0.1 ::1] +[certs] Generating "etcd/peer" certificate and key +[certs] etcd/peer serving cert is signed for DNS names [k8s-master-1 localhost] and IPs [192.168.0.127 127.0.0.1 ::1] +[certs] Generating "etcd/healthcheck-client" certificate and key +[certs] Generating "apiserver-etcd-client" certificate and key +[certs] Generating "ca" certificate and key +[certs] Generating "apiserver-kubelet-client" certificate and key +[certs] Generating "apiserver" certificate and key +[certs] apiserver serving cert is signed for DNS names [k8s-master-1 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.0.127] +[certs] Generating "sa" key and public key +[kubeconfig] Using kubeconfig folder "/etc/kubernetes" +[kubeconfig] Writing "admin.conf" kubeconfig file +[kubeconfig] Writing "kubelet.conf" kubeconfig file +[kubeconfig] Writing "controller-manager.conf" kubeconfig file +[kubeconfig] Writing "scheduler.conf" kubeconfig file +[control-plane] Using manifest folder "/etc/kubernetes/manifests" +[control-plane] Creating static Pod manifest for "kube-apiserver" +[control-plane] Creating static Pod manifest for "kube-controller-manager" +[control-plane] Creating static Pod manifest for "kube-scheduler" +[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests" +[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s +[apiclient] All control plane components are healthy after 19.001686 seconds +[uploadconfig] storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace +[kubelet] Creating a ConfigMap "kubelet-config-1.13" in namespace kube-system with the configuration for the kubelets in the cluster +[patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "k8s-master-1" as an annotation +[mark-control-plane] Marking the node k8s-master-1 as control-plane by adding the label "node-role.kubernetes.io/master=''" +[mark-control-plane] Marking the node k8s-master-1 as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule] +[bootstrap-token] Using token: 8tpo9l.jlw135r8559kaad4 +[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles +[bootstraptoken] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials +[bootstraptoken] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token +[bootstraptoken] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster +[bootstraptoken] creating the "cluster-info" ConfigMap in the "kube-public" namespace +[addons] Applied essential addon: CoreDNS +[addons] Applied essential addon: kube-proxy + +Your Kubernetes master has initialized successfully! + +To start using your cluster, you need to run the following as a regular user: + + mkdir -p $HOME/.kube + sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config + sudo chown $(id -u):$(id -g) $HOME/.kube/config + +You should now deploy a pod network to the cluster. +Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: + https://kubernetes.io/docs/concepts/cluster-administration/addons/ + +You can now join any number of machines by running the following on each node +as root: + + kubeadm join 192.168.0.127:6443 --token 8tpo9l.jlw135r8559kaad4 --discovery-token-ca-cert-hash sha256:d6594ccc1310a45cbebc45f1c93f5ac113873786365ed63efcf667c952d7d197 +``` + +- 给 master 机子设置配置 + +``` +mkdir -p $HOME/.kube +sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config +sudo chown $(id -u):$(id -g) $HOME/.kube/config +export KUBECONFIG=$HOME/.kube/config +``` + +- 在 master 上查看一些环境 + +``` +kubeadm token list + +kubectl cluster-info +``` + +- 给 master 安装 Flannel + +``` +cd /opt && wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml + +kubectl apply -f /opt/kube-flannel.yml +``` + +- 到 node 节点加入集群: + +``` +echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables + +kubeadm join 192.168.0.127:6443 --token 8tpo9l.jlw135r8559kaad4 --discovery-token-ca-cert-hash sha256:d6594ccc1310a45cbebc45f1c93f5ac113873786365ed63efcf667c952d7d197 + +这时候终端会输出: + +[preflight] Running pre-flight checks +[discovery] Trying to connect to API Server "192.168.0.127:6443" +[discovery] Created cluster-info discovery client, requesting info from "https://192.168.0.127:6443" +[discovery] Requesting info from "https://192.168.0.127:6443" again to validate TLS against the pinned public key +[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "192.168.0.127:6443" +[discovery] Successfully established connection with API Server "192.168.0.127:6443" +[join] Reading configuration from the cluster... +[join] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml' +[kubelet] Downloading configuration for the kubelet from the "kubelet-config-1.13" ConfigMap in the kube-system namespace +[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" +[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env" +[kubelet-start] Activating the kubelet service +[tlsbootstrap] Waiting for the kubelet to perform the TLS Bootstrap... +[patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "k8s-node-1" as an annotation + +This node has joined the cluster: +* Certificate signing request was sent to apiserver and a response was received. +* The Kubelet was informed of the new secure connection details. + +Run 'kubectl get nodes' on the master to see this node join the cluster. +``` + +- 如果 node 节点加入失败,可以:`kubeadm reset`,再来重新 join +- 在 master 节点上:`kubectl get cs` + +``` +NAME STATUS MESSAGE ERROR +controller-manager Healthy ok +scheduler Healthy ok +etcd-0 Healthy {"health": "true"} +结果都是 Healthy 则表示可以了,不然就得检查。必要时可以用:`kubeadm reset` 重置,重新进行集群初始化 +``` + + +- 在 master 节点上:`kubectl get nodes` + +``` +如果还是 NotReady,则查看错误信息:kubectl get pods --all-namespaces +其中:Pending/ContainerCreating/ImagePullBackOff 都是 Pod 没有就绪,我们可以这样查看对应 Pod 遇到了什么问题 +kubectl describe pod --namespace=kube-system +或者:kubectl logs -n kube-system +tail -f /var/log/messages +``` + + + +#### 主要概念 + +- Master 节点,负责集群的调度、集群的管理 + - 常见组件: + - kube-apiserver:API服务 + - kube-scheduler:调度 + - Kube-Controller-Manager:容器编排 + - Etcd:保存了整个集群的状态 + - Kube-proxy:负责为 Service 提供 cluster 内部的服务发现和负载均衡 + - Kube-DNS:负责为整个集群提供 DNS 服务 +- node 节点,负责容器相关的处理 + +- `Pods` + +``` +创建,调度以及管理的最小单元 +共存的一组容器的集合 +容器共享PID,网络,IPC以及UTS命名空间 +容器共享存储卷 +短暂存在 +``` + +- `Volumes` + +``` +数据持久化 +Pod中容器共享数据 +生命周期 +支持多种类型的数据卷 – emptyDir, hostpath, gcePersistentDisk, awsElasticBlockStore, nfs, iscsi, glusterfs, secrets +``` + +- `Labels` + +``` +用以标示对象(如Pod)的key/value对 +组织并选择对象子集 +``` + +- `Replication Controllers` + +``` +确保在任一时刻运行指定数目的Pod +容器重新调度 +规模调整 +在线升级 +多发布版本跟踪 +``` + +- `Services` + +``` +抽象一系列Pod并定义其访问规则 +固定IP地址和DNS域名 +通过环境变量和DNS发现服务 +负载均衡 +外部服务 – ClusterIP, NodePort, LoadBalancer +``` + + +#### 主要组成模块 + +- `etcd` + +``` +高可用的Key/Value存储 +只有apiserver有读写权限 +使用etcd集群确保数据可靠性 +``` + +- `apiserver` + +``` +Kubernetes系统入口, REST +认证 +授权 +访问控制 +服务帐号 +资源限制 +``` + +- `kube-scheduler` + +``` +资源需求 +服务需求 +硬件/软件/策略限制 +关联性和非关联性 +数据本地化 +``` + +- `kube-controller-manager` + +``` +Replication controller +Endpoint controller +Namespace controller +Serviceaccount controller +``` + +- `kubelet` + +``` +节点管理器 +确保调度到本节点的Pod的运行和健康 +``` + +- `kube-proxy` + +``` +Pod网络代理 +TCP/UDP请求转发 +负载均衡(Round Robin) +``` + +- `服务发现` + +``` +环境变量 +DNS – kube2sky, etcd,skydns +``` + +- `网络` + +``` +容器间互相通信 +节点和容器间互相通信 +每个Pod使用一个全局唯一的IP +``` + +- `高可用` + +``` +kubelet保证每一个master节点的服务正常运行 +系统监控程序确保kubelet正常运行 +Etcd集群 +多个apiserver进行负载均衡 +Master选举确保kube-scheduler和kube-controller-manager高可用 +``` + + +## 资料 + +- [如何更“优雅”地部署Kubernetes集群](https://juejin.im/entry/5a03f98d6fb9a04524054516) +- []() +- []() +- []() +- []() +- []() +- []() + + + + + + + + + + + + + + + + + + + + + diff --git a/markdown-file/Kafka-Install-And-Settings.md b/markdown-file/Kafka-Install-And-Settings.md new file mode 100644 index 00000000..ff67a925 --- /dev/null +++ b/markdown-file/Kafka-Install-And-Settings.md @@ -0,0 +1,665 @@ +# Kafka 安装和配置 + + +## 对于版本 + +- 由于 Kafka 经常会被连接到各个地方去,所以对于 Kafka 的版本,一般不能用太新的,要看你用在什么地方。 +- [Flink 的要求](https://ci.apache.org/projects/flink/flink-docs-release-1.6/dev/connectors/kafka.html) +- [Spark 的要求](https://spark.apache.org/docs/latest/streaming-kafka-integration.html) +- [Spring 的要求](http://projects.spring.io/spring-kafka/) + + +## 消息系统的好处 + +- 解耦(各个业务系统各自为政,有各自新需求,各自系统自行修改,只通过消息来通信) +- 大系统层面的扩展性(不用改旧业务系统代码,增加新系统,接收新消息) +- 异步通信(一个消息,多个业务系统来消费。某些场景可以堆积到一定程度再去消费) +- 缓冲(解耦某些需要长时间处理业务) + + +## Kafka 介绍 + +> A distributed streaming platform + +- 官网: +- Github: + - 主要是由 Java 和 Scala 开发 +- 官网下载: +- 当前最新稳定版本(201803):**1.0.1** +- 官网 quickstart: +- 运行的机子不要小于 2G 内存 +- Kafka 流行的主要原因: + - 支持常见的发布订阅功能 + - 分布式 + - 高吞吐量(听说:普通单机也支持每秒 100000 条消息的传输) + - 磁盘数据持久化,消费者 down 后,重新 up 的时候可以继续接收前面未接收到的消息 + - 支持流数据处理,常见于大数据 +- 核心概念: + - Producer:生产者(业务系统),负责发布消息到 broker + - Consumer:消费者(业务系统),向 broker 读取消息的客户端 + - Broker:可以理解为:存放消息的管道(kafka 软件节点本身) + - Topic:可以理解为:消息主题、消息标签、消息通道、消息队列(物理上不同 Topic 的消息分开存储,根据 Partition 参数决定一个 Topic 的消息保存于一个或多个 broker 上。作为使用者,不用关心 Topic 实际物理存储地方。) + - Partition:是物理上的概念,每个 Topic 包含一个或多个 Partition。一般有几个 Broker,填写分区最好是等于大于节点值。分区目的主要是数据分片,解决水平扩展、高吞吐量。当 Producer 生产消息的时候,消息会被算法计算后分配到对应的分区,Consumer 读取的时候算法也会帮我们找到消息所在分区,这是内部实现的,应用层面不用管。 + - Replication-factor:副本。假设有 3 个 Broker 的情况下,当副本为 3 的时候每个 Partition 会在每个 Broker 都会存有一份,目的主要是容错。 + - 其中有一个 Leader。 + - 如果你只有一个 Broker,但是创建 Topic 的时候指定 Replication-factor 为 3,则会报错 + - Consumer Group:每个 Consumer 属于一个特定的 Consumer Group(可为每个 Consumer 指定 group name,若不指定 group name 则属于默认的 group)一般一个业务系统集群指定同一个一个 group id,然后一个业务系统集群只能一个节点来消费同一个消息。 + - Consumer Group 信息存储在 zookeeper 中,需要通过 zookeeper 的客户端来查看和设置 + - 如果某 Consumer Group 中 consumer 数量少于 partition 数量,则至少有一个 consumer 会消费多个 partition 的数据 + - 如果 consumer 的数量与 partition 数量相同,则正好一个 consumer 消费一个 partition 的数据 + - 如果 consumer 的数量多于 partition 的数量时,会有部分 consumer 无法消费该 topic 下任何一条消息。 + - 具体实验可以看这篇文章:[Kafka深度解析](http://www.jasongj.com/2015/01/02/Kafka%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90/) + - Record:消息数据本身,由一个 key、value、timestamp 组成 +- 业界常用的 docker 镜像: + - [wurstmeister/kafka-docker(不断更新,优先)](https://github.com/wurstmeister/kafka-docker/) + - Spring 项目选用依赖包的时候,对于版本之间的关系可以看这里: + - 目前(201803) + - spring boot 2.0 以上基础框架版本,kafka 版本 1.0.x,推荐使用:spring-kafka 2.1.4.RELEASE + - spring boot 2.0 以下基础框架版本,kafka 版本 0.11.0.x, 1.0.x,推荐使用:spring-kafka 1.3.3.RELEASE +- 官网 quickstart 指导: +- 常用命令: + - wurstmeister/kafka-docker 容器中 kafka home:`cd /opt/kafka` + - 假设我的 zookeeper 地址:`10.135.157.34:2181`,如果你有多个节点用逗号隔开 + - 列出所有 topic:`bin/kafka-topics.sh --list --zookeeper 10.135.157.34:2181` + - 创建 topic:`bin/kafka-topics.sh --create --topic kafka-test-topic-1 --partitions 3 --replication-factor 1 --zookeeper 10.135.157.34:2181` + - 创建名为 kafka-test-topic-1 的 topic,3个分区分别存放数据,数据备份总共 2 份 + - 查看特定 topic 的详情:`bin/kafka-topics.sh --describe --topic kafka-test-topic-1 --zookeeper 10.135.157.34:2181` + - 删除 topic:`bin/kafka-topics.sh --delete --topic kafka-test-topic-1 --zookeeper 10.135.157.34:2181` + - 更多命令可以看: +- 假设 topic 详情的返回信息如下: + - `PartitionCount:6`:分区为 6 个 + - `ReplicationFactor:3`:副本为 3 个 + - `Partition: 0 Leader: 3`:Partition 下标为 0 的主节点是 broker.id=3 + - 当 Leader down 掉之后,其他节点会选举中一个新 Leader + - `Replicas: 3,1,2`:在 `Partition: 0` 下共有 3 个副本,broker.id 分别为 3,1,2 + - `Isr: 3,1,2`:在 `Partition: 0` 下目前存活的 broker.id 分别为 3,1,2 + +``` +Topic:kafka-all PartitionCount:6 ReplicationFactor:3 Configs: + Topic: kafka-all Partition: 0 Leader: 3 Replicas: 3,1,2 Isr: 3,1,2 + Topic: kafka-all Partition: 1 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3 + Topic: kafka-all Partition: 2 Leader: 2 Replicas: 2,3,1 Isr: 2,3,1 + Topic: kafka-all Partition: 3 Leader: 3 Replicas: 3,2,1 Isr: 3,2,1 + Topic: kafka-all Partition: 4 Leader: 1 Replicas: 1,3,2 Isr: 1,3,2 + Topic: kafka-all Partition: 5 Leader: 2 Replicas: 2,1,3 Isr: 2,1,3 +``` + + +---------------------------------------------------------------------------------------------- + + +## Docker 单个实例部署(1.0.1) + +- 目前 latest 用的时候 kafka 1.0.1,要指定版本可以去作者 [github](https://github.com/wurstmeister/kafka-docker) 看下 tag 目录,切换不同 tag,然后看下 Dockerfile 里面的 kafka 版本号 +- 我的服务器外网 ip:`182.61.19.177`,hostname 为:`instance-3v0pbt5d` +- 在我的开发机上上配置 host: + +``` +182.61.19.177 instance-3v0pbt5d +``` + +- 部署 kafka: +- 目前 latest 用的时候 kafka 1.0.1,要指定版本可以去作者 [github](https://github.com/wurstmeister/kafka-docker) 看下 tag 目录,切换不同 tag,然后看下 Dockerfile 里面的 kafka 版本号 +- 新建文件:`vim docker-compose.yml` +- 这里的 kafka 对外网暴露端口是 9094,内网端口是 9092 + +``` +version: '3.2' +services: + zookeeper: + image: wurstmeister/zookeeper + ports: + - "2181:2181" + kafka: + image: wurstmeister/kafka:latest + ports: + - target: 9094 + published: 9094 + protocol: tcp + mode: host + environment: + HOSTNAME_COMMAND: "docker info | grep ^Name: | cut -d' ' -f 2" + KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT + KAFKA_ADVERTISED_PROTOCOL_NAME: OUTSIDE + KAFKA_ADVERTISED_PORT: 9094 + KAFKA_PROTOCOL_NAME: INSIDE + KAFKA_PORT: 9092 + KAFKA_LOG_DIRS: /data/docker/kafka/logs + KAFKA_AUTO_CREATE_TOPICS_ENABLE: 'true' + KAFKA_LOG_RETENTION_HOURS: 168 + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /data/docker/kafka/logs:/data/docker/kafka/logs +``` + +- 启动:`docker-compose up -d` +- 停止:`docker-compose stop` +- 测试: + - 进入 kafka 容器:`docker exec -it kafkadocker_kafka_1 /bin/bash` + - 根据官网 Dockerfile 说明,kafka home 应该是:`cd /opt/kafka` + - 创建 topic 命令:`bin/kafka-topics.sh --create --zookeeper zookeeper:2181 --replication-factor 1 --partitions 1 --topic my-topic-test` + - 查看 topic 命令:`bin/kafka-topics.sh --list --zookeeper zookeeper:2181` + - 删除 topic:`bin/kafka-topics.sh --delete --topic my-topic-test --zookeeper zookeeper:2181` + - 给 topic 发送消息命令:`bin/kafka-console-producer.sh --broker-list localhost:9092 --topic my-topic-test`,然后在出现交互输入框的时候输入你要发送的内容 + - 再开一个终端,进入 kafka 容器,接受消息:`bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic my-topic-test --from-beginning` + - 其中 `--from-beginning` 参数表示在启动该客户端的时候接受前面 kafka 的所有记录。不加这个参数,则旧数据不会收到,生产者新生产的消息才会接收到。 + - 此时发送的终端输入一个内容回车,接受消息的终端就可以收到。 + +---------------------------------------------------------------------------------------------- + + +## Docker 多机多实例部署(外网无法访问) + +- 三台机子: + - 内网 ip:`172.24.165.129`,外网 ip:`47.91.22.116` + - 内网 ip:`172.24.165.130`,外网 ip:`47.91.22.124` + - 内网 ip:`172.24.165.131`,外网 ip:`47.74.6.138` +- 修改三台机子 hostname: + - 节点 1:`hostnamectl --static set-hostname youmeekhost1` + - 节点 2:`hostnamectl --static set-hostname youmeekhost2` + - 节点 3:`hostnamectl --static set-hostname youmeekhost3` +- 三台机子的 hosts 都修改为如下内容:`vim /etc/hosts` + +``` +172.24.165.129 youmeekhost1 +172.24.165.130 youmeekhost2 +172.24.165.131 youmeekhost3 +``` + +- 开发机设置 hosts: + +``` +47.91.22.116 youmeekhost1 +47.91.22.124 youmeekhost2 +47.74.6.138 youmeekhost3 +``` + + +#### Zookeeper 集群 + +- 节点 1: + +``` +docker run -d --name=zookeeper1 --net=host --restart=always \ +-v /data/docker/zookeeper/data:/data \ +-v /data/docker/zookeeper/log:/datalog \ +-v /etc/hosts:/etc/hosts \ +-e ZOO_MY_ID=1 \ +-e "ZOO_SERVERS=server.1=youmeekhost1:2888:3888 server.2=youmeekhost2:2888:3888 server.3=youmeekhost3:2888:3888" \ +zookeeper:latest +``` + + +- 节点 2: + +``` +docker run -d --name=zookeeper2 --net=host --restart=always \ +-v /data/docker/zookeeper/data:/data \ +-v /data/docker/zookeeper/log:/datalog \ +-v /etc/hosts:/etc/hosts \ +-e ZOO_MY_ID=2 \ +-e "ZOO_SERVERS=server.1=youmeekhost1:2888:3888 server.2=youmeekhost2:2888:3888 server.3=youmeekhost3:2888:3888" \ +zookeeper:latest +``` + + +- 节点 3: + +``` +docker run -d --name=zookeeper3 --net=host --restart=always \ +-v /data/docker/zookeeper/data:/data \ +-v /data/docker/zookeeper/log:/datalog \ +-v /etc/hosts:/etc/hosts \ +-e ZOO_MY_ID=3 \ +-e "ZOO_SERVERS=server.1=youmeekhost1:2888:3888 server.2=youmeekhost2:2888:3888 server.3=youmeekhost3:2888:3888" \ +zookeeper:latest +``` + + + +#### 先安装 nc 再来校验 zookeeper 集群情况 + +- 环境:CentOS 7.4 +- 官网下载:,找到 rpm 包 +- 当前时间(201803)最新版本下载:`wget https://nmap.org/dist/ncat-7.60-1.x86_64.rpm` +- 安装并 ln:`sudo rpm -i ncat-7.60-1.x86_64.rpm && ln -s /usr/bin/ncat /usr/bin/nc` +- 检验:`nc --version` + +#### zookeeper 集群测试 + +- 节点 1 执行命令:`echo stat | nc youmeekhost1 2181`,能得到如下信息: + +``` +Zookeeper version: 3.4.11-37e277162d567b55a07d1755f0b31c32e93c01a0, built on 11/01/2017 18:06 GMT +Clients: + /172.31.154.16:35336[0](queued=0,recved=1,sent=0) + +Latency min/avg/max: 0/0/0 +Received: 1 +Sent: 0 +Connections: 1 +Outstanding: 0 +Zxid: 0x0 +Mode: follower +Node count: 4 +``` + +- 节点 2 执行命令:`echo stat | nc youmeekhost2 2181`,能得到如下信息: + +``` +Zookeeper version: 3.4.11-37e277162d567b55a07d1755f0b31c32e93c01a0, built on 11/01/2017 18:06 GMT +Clients: + /172.31.154.17:55236[0](queued=0,recved=1,sent=0) + +Latency min/avg/max: 0/0/0 +Received: 1 +Sent: 0 +Connections: 1 +Outstanding: 0 +Zxid: 0x100000000 +Mode: leader +Node count: 4 +``` + +- 节点 3 执行命令:`echo stat | nc youmeekhost3 2181`,能得到如下信息: + +``` +Zookeeper version: 3.4.11-37e277162d567b55a07d1755f0b31c32e93c01a0, built on 11/01/2017 18:06 GMT +Clients: + /172.31.65.88:41840[0](queued=0,recved=1,sent=0) + +Latency min/avg/max: 0/0/0 +Received: 1 +Sent: 0 +Connections: 1 +Outstanding: 0 +Zxid: 0x100000000 +Mode: follower +Node count: 4 +``` + +##### Kafka 集群 + +- 节点 1 执行: + +``` +docker run -d --net=host --name=kafka1 \ +--restart=always \ +--env KAFKA_BROKER_ID=1 \ +--env KAFKA_ZOOKEEPER_CONNECT=youmeekhost1:2181,youmeekhost2:2181,youmeekhost3:2181 \ +--env KAFKA_LOG_DIRS=/data/docker/kafka/logs \ +--env HOSTNAME_COMMAND="docker info | grep ^Name: | cut -d' ' -f 2" \ +--env KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT \ +--env KAFKA_ADVERTISED_PROTOCOL_NAME=OUTSIDE \ +--env KAFKA_ADVERTISED_PORT=9094 \ +--env KAFKA_PROTOCOL_NAME=INSIDE \ +--env KAFKA_PORT=9092 \ +--env KAFKA_AUTO_CREATE_TOPICS_ENABLE=true \ +--env KAFKA_LOG_RETENTION_HOURS=168 \ +--env KAFKA_HEAP_OPTS="-Xmx1G -Xms1G" \ +-v /var/run/docker.sock:/var/run/docker.sock \ +-v /etc/localtime:/etc/localtime \ +-v /data/docker/kafka/logs:/data/docker/kafka/logs \ +-v /etc/hosts:/etc/hosts \ +wurstmeister/kafka:latest +``` + +- 节点 2 执行: + +``` +docker run -d --net=host --name=kafka2 \ +--restart=always \ +--env KAFKA_BROKER_ID=2 \ +--env KAFKA_ZOOKEEPER_CONNECT=youmeekhost1:2181,youmeekhost2:2181,youmeekhost3:2181 \ +--env KAFKA_LOG_DIRS=/data/docker/kafka/logs \ +--env HOSTNAME_COMMAND="docker info | grep ^Name: | cut -d' ' -f 2" \ +--env KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT \ +--env KAFKA_ADVERTISED_PROTOCOL_NAME=OUTSIDE \ +--env KAFKA_ADVERTISED_PORT=9094 \ +--env KAFKA_PROTOCOL_NAME=INSIDE \ +--env KAFKA_PORT=9092 \ +--env KAFKA_AUTO_CREATE_TOPICS_ENABLE=true \ +--env KAFKA_LOG_RETENTION_HOURS=168 \ +--env KAFKA_HEAP_OPTS="-Xmx1G -Xms1G" \ +-v /var/run/docker.sock:/var/run/docker.sock \ +-v /etc/localtime:/etc/localtime \ +-v /data/docker/kafka/logs:/data/docker/kafka/logs \ +-v /etc/hosts:/etc/hosts \ +wurstmeister/kafka:latest +``` + +- 节点 3 执行: + +``` +docker run -d --net=host --name=kafka3 \ +--restart=always \ +--env KAFKA_BROKER_ID=3 \ +--env KAFKA_ZOOKEEPER_CONNECT=youmeekhost1:2181,youmeekhost2:2181,youmeekhost3:2181 \ +--env KAFKA_LOG_DIRS=/data/docker/kafka/logs \ +--env HOSTNAME_COMMAND="docker info | grep ^Name: | cut -d' ' -f 2" \ +--env KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT \ +--env KAFKA_ADVERTISED_PROTOCOL_NAME=OUTSIDE \ +--env KAFKA_ADVERTISED_PORT=9094 \ +--env KAFKA_PROTOCOL_NAME=INSIDE \ +--env KAFKA_PORT=9092 \ +--env KAFKA_AUTO_CREATE_TOPICS_ENABLE=true \ +--env KAFKA_LOG_RETENTION_HOURS=168 \ +--env KAFKA_HEAP_OPTS="-Xmx1G -Xms1G" \ +-v /var/run/docker.sock:/var/run/docker.sock \ +-v /etc/localtime:/etc/localtime \ +-v /data/docker/kafka/logs:/data/docker/kafka/logs \ +-v /etc/hosts:/etc/hosts \ +wurstmeister/kafka:latest +``` + +#### Kafka 集群测试 + +- 在 kafka1 上测试: + - 进入 kafka1 容器:`docker exec -it kafka1 /bin/bash` + - 根据官网 Dockerfile 说明,kafka home 应该是:`cd /opt/kafka` + - 创建 topic 命令:`bin/kafka-topics.sh --create --zookeeper youmeekhost1:2181,youmeekhost2:2181,youmeekhost3:2181 --replication-factor 3 --partitions 3 --topic my-topic-test` + - 查看 topic 命令:`bin/kafka-topics.sh --list --zookeeper youmeekhost1:2181,youmeekhost2:2181,youmeekhost3:2181` + - 给 topic 发送消息命令:`bin/kafka-console-producer.sh --broker-list youmeekhost1:9092 --topic my-topic-test`,然后在出现交互输入框的时候输入你要发送的内容 +- 在 kafka2 上测试: + - 进入 kafka2 容器:`docker exec -it kafka2 /bin/bash` + - 接受消息:`cd /opt/kafka && bin/kafka-console-consumer.sh --bootstrap-server youmeekhost2:9092 --topic my-topic-test --from-beginning` +- 在 kafka3 上测试: + - 进入 kafka3 容器:`docker exec -it kafka3 /bin/bash` + - 接受消息:`cd /opt/kafka && bin/kafka-console-consumer.sh --bootstrap-server youmeekhost3:9092 --topic my-topic-test --from-beginning` +- 如果 kafka1 输入的消息,kafka2 和 kafka3 能收到,则表示已经成功。 + + +#### Kafka 认证配置 + +- 可以参考:[Kafka的SASL/PLAIN认证配置说明](http://www.2bowl.info/kafka%e7%9a%84saslplain%e8%ae%a4%e8%af%81%e9%85%8d%e7%bd%ae%e8%af%b4%e6%98%8e/) + + +#### Kafka 单纯监控 KafkaOffsetMonitor + +- Github 官网: + - README 带了下载地址和运行命令 + - 只是已经很久不更新了 + +#### 部署 kafka-manager + +- Github 官网: + - 注意官网说明的版本支持 +- 节点 1(没成功):`docker run -d --name=kafka-manager1 --restart=always -p 9000:9000 -e ZK_HOSTS="youmeekhost1:2181,youmeekhost2:2181,youmeekhost3:2181" sheepkiller/kafka-manager:latest` +- 源码类安装可以看:[Kafka监控工具—Kafka Manager](http://www.2bowl.info/kafka%e7%9b%91%e6%8e%a7%e5%b7%a5%e5%85%b7-kafka-manager/) +- Kafka manager 是一款管理 + 监控的工具,比较重 + + + +---------------------------------------------------------------------------------------------- + +## Kafka 1.0.1 源码安装(也支持 1.0.2、0.11.0.3、0.10.2.2) + +- 测试环境:2G 内存足够 +- 一台机子:CentOS 7.4,根据文章最开头,已经修改了 hosts +- 确保本机安装有 JDK8(JDK 版本不能随便挑选) +- 先用上面的 docker 方式部署一个 zookeeper,我这里的 zookeeper IP 地址为:`172.16.0.2` + - **如果该 zookeeper 前面已经用过了,最好重新删除,重新 run,因为 zookeeper 上保留的旧的 topic 配置** +- 官网下载: +- 当前(201803)最新版本为:**1.0.1,同时推荐 Scala 版本为 2.11**,这里要特别注意:kafka_2.11-1.0.1.tgz 中的 2.11 指的是 Scala 版本 + - 找到:`Binary downloads` 下面的链接 + - 下载:`wget http://mirrors.shu.edu.cn/apache/kafka/1.0.1/kafka_2.11-1.0.1.tgz` +- 解压:`tar zxvf kafka_2.11-1.0.1.tgz`,假设当前目录为:`/usr/local/kafka_2.11-1.0.1` +- 为了方便,修改目录名字:`mv /usr/local/kafka_2.11-1.0.1 /usr/local/kafka` +- 创建 log 输出目录:`mkdir -p /data/kafka/logs` +- 修改 kafka-server 的配置文件:`vim /usr/local/kafka/config/server.properties` +- 找到下面两个参数内容,修改成如下: + +``` +# 唯一ID(kafka 集群环境下,该值必须唯一,默认从 0 开始),和 zookeeper 的配置文件中的 myid 类似道理(单节点多 broker 的情况下该参数必改) +broker.id=1 +# 监听地址(单节点多 broker 的情况下该参数必改) +listeners=PLAINTEXT://0.0.0.0:9092 +# 向 Zookeeper 注册的地址。这里可以直接填写外网IP地址,但是不建议这样做,而是通过配置 hosts 的方式来设置。不然填写外网 IP 地址会导致所有流量都走外网(单节点多 broker 的情况下该参数必改) +advertised.listeners=PLAINTEXT://youmeekhost:9092 +# zookeeper,存储了 broker 的元信息 +zookeeper.connect=youmeekhost:2181 +# 日志数据目录,可以通过逗号来指定多个目录(单节点多 broker 的情况下该参数必改) +log.dirs=/data/kafka/logs +# 创建新 topic 的时候默认 1 个分区。需要特别注意的是:已经创建好的 topic 的 partition 的个数只可以被增加,不能被减少。 +# 如果对消息有高吞吐量的要求,可以增加分区数来分摊压力 +num.partitions=1 +# 允许删除topic +delete.topic.enable=false +# 允许自动创建topic(默认是 true) +auto.create.topics.enable=true +# 磁盘IO不足的时候,可以适当调大该值 ( 当内存足够时 ) +#log.flush.interval.messages=10000 +#log.flush.interval.ms=1000 +# kafka 数据保留时间 默认 168 小时 == 7 天 +log.retention.hours=168 + + +# 其余都使用默认配置,但是顺便解释下: +# borker 进行网络处理的线程数 +num.network.threads=3 + +# borker 进行 I/O 处理的线程数 +num.io.threads=8 + +# 发送缓冲区 buffer 大小,数据不是一下子就发送的,先回存储到缓冲区了到达一定的大小后在发送,能提高性能 +socket.send.buffer.bytes=102400 + +# 接收缓冲区大小,当数据到达一定大小后在序列化到磁盘 +socket.receive.buffer.bytes=102400 + +# 这个参数是向 kafka 请求消息或者向 kafka 发送消息的请请求的最大数,这个值不能超过 java 的堆栈大小 +socket.request.max.bytes=104857600 +``` + +- 启动 kafka 服务(必须制定配置文件):`cd /usr/local/kafka && bin/kafka-server-start.sh config/server.properties` + - 后台方式运行 kafka 服务:`cd /usr/local/kafka && bin/kafka-server-start.sh -daemon config/server.properties` + - 停止 kafka 服务:`cd /usr/local/kafka && bin/kafka-server-stop.sh` +- 再开一个终端测试: + - 创建 topic 命令:`cd /usr/local/kafka && bin/kafka-topics.sh --create --zookeeper youmeekhost:2181 --replication-factor 1 --partitions 1 --topic my-topic-test` + - 查看 topic 命令:`cd /usr/local/kafka && bin/kafka-topics.sh --list --zookeeper youmeekhost:2181` + - 删除 topic:`cd /usr/local/kafka && bin/kafka-topics.sh --delete --topic my-topic-test --zookeeper youmeekhost:2181` + - 给 topic 发送消息命令:`cd /usr/local/kafka && bin/kafka-console-producer.sh --broker-list youmeekhost:9092 --topic my-topic-test`,然后在出现交互输入框的时候输入你要发送的内容 + - 再开一个终端,进入 kafka 容器,接受消息:`cd /usr/local/kafka && bin/kafka-console-consumer.sh --bootstrap-server youmeekhost:9092 --topic my-topic-test --from-beginning` + - 此时发送的终端输入一个内容回车,接受消息的终端就可以收到。 +- Spring Boot 依赖: + +```xml + + org.springframework.kafka + spring-kafka + 1.3.3.RELEASE + + + + org.apache.kafka + kafka-clients + 1.0.1 + + + + org.apache.kafka + kafka-streams + 1.0.1 + +``` + +- 项目配置文件:bootstrap-servers 地址:`instance-3v0pbt5d:9092`(这里端口是 9092 别弄错了) + +---------------------------------------------------------------------------------------------- + +## kafka 1.0.1 默认配置文件内容 + +``` +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# see kafka.server.KafkaConfig for additional details and defaults + +############################# Server Basics ############################# + +# The id of the broker. This must be set to a unique integer for each broker. +broker.id=0 + +############################# Socket Server Settings ############################# + +# The address the socket server listens on. It will get the value returned from +# java.net.InetAddress.getCanonicalHostName() if not configured. +# FORMAT: +# listeners = listener_name://host_name:port +# EXAMPLE: +# listeners = PLAINTEXT://your.host.name:9092 +#listeners=PLAINTEXT://:9092 + +# Hostname and port the broker will advertise to producers and consumers. If not set, +# it uses the value for "listeners" if configured. Otherwise, it will use the value +# returned from java.net.InetAddress.getCanonicalHostName(). +#advertised.listeners=PLAINTEXT://your.host.name:9092 + +# Maps listener names to security protocols, the default is for them to be the same. See the config documentation for more details +#listener.security.protocol.map=PLAINTEXT:PLAINTEXT,SSL:SSL,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_SSL:SASL_SSL + +# The number of threads that the server uses for receiving requests from the network and sending responses to the network +num.network.threads=3 + +# The number of threads that the server uses for processing requests, which may include disk I/O +num.io.threads=8 + +# The send buffer (SO_SNDBUF) used by the socket server +socket.send.buffer.bytes=102400 + +# The receive buffer (SO_RCVBUF) used by the socket server +socket.receive.buffer.bytes=102400 + +# The maximum size of a request that the socket server will accept (protection against OOM) +socket.request.max.bytes=104857600 + + +############################# Log Basics ############################# + +# A comma seperated list of directories under which to store log files +log.dirs=/tmp/kafka-logs + +# The default number of log partitions per topic. More partitions allow greater +# parallelism for consumption, but this will also result in more files across +# the brokers. +num.partitions=1 + +# The number of threads per data directory to be used for log recovery at startup and flushing at shutdown. +# This value is recommended to be increased for installations with data dirs located in RAID array. +num.recovery.threads.per.data.dir=1 + +############################# Internal Topic Settings ############################# +# The replication factor for the group metadata internal topics "__consumer_offsets" and "__transaction_state" +# For anything other than development testing, a value greater than 1 is recommended for to ensure availability such as 3. +offsets.topic.replication.factor=1 +transaction.state.log.replication.factor=1 +transaction.state.log.min.isr=1 + +############################# Log Flush Policy ############################# + +# Messages are immediately written to the filesystem but by default we only fsync() to sync +# the OS cache lazily. The following configurations control the flush of data to disk. +# There are a few important trade-offs here: +# 1. Durability: Unflushed data may be lost if you are not using replication. +# 2. Latency: Very large flush intervals may lead to latency spikes when the flush does occur as there will be a lot of data to flush. +# 3. Throughput: The flush is generally the most expensive operation, and a small flush interval may lead to exceessive seeks. +# The settings below allow one to configure the flush policy to flush data after a period of time or +# every N messages (or both). This can be done globally and overridden on a per-topic basis. + +# The number of messages to accept before forcing a flush of data to disk +#log.flush.interval.messages=10000 + +# The maximum amount of time a message can sit in a log before we force a flush +#log.flush.interval.ms=1000 + +############################# Log Retention Policy ############################# + +# The following configurations control the disposal of log segments. The policy can +# be set to delete segments after a period of time, or after a given size has accumulated. +# A segment will be deleted whenever *either* of these criteria are met. Deletion always happens +# from the end of the log. + +# The minimum age of a log file to be eligible for deletion due to age +log.retention.hours=168 + +# A size-based retention policy for logs. Segments are pruned from the log unless the remaining +# segments drop below log.retention.bytes. Functions independently of log.retention.hours. +#log.retention.bytes=1073741824 + +# The maximum size of a log segment file. When this size is reached a new log segment will be created. +log.segment.bytes=1073741824 + +# The interval at which log segments are checked to see if they can be deleted according +# to the retention policies +log.retention.check.interval.ms=300000 + +############################# Zookeeper ############################# + +# Zookeeper connection string (see zookeeper docs for details). +# This is a comma separated host:port pairs, each corresponding to a zk +# server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002". +# You can also append an optional chroot string to the urls to specify the +# root directory for all kafka znodes. +zookeeper.connect=localhost:2181 + +# Timeout in ms for connecting to zookeeper +zookeeper.connection.timeout.ms=6000 + + +############################# Group Coordinator Settings ############################# + +# The following configuration specifies the time, in milliseconds, that the GroupCoordinator will delay the initial consumer rebalance. +# The rebalance will be further delayed by the value of group.initial.rebalance.delay.ms as new members join the group, up to a maximum of max.poll.interval.ms. +# The default value for this is 3 seconds. +# We override this to 0 here as it makes for a better out-of-the-box experience for development and testing. +# However, in production environments the default value of 3 seconds is more suitable as this will help to avoid unnecessary, and potentially expensive, rebalances during application startup. +group.initial.rebalance.delay.ms=0 +``` + + +---------------------------------------------------------------------------------------------- + + +## 其他资料 + +- [管理Kafka的Consumer-Group信息](http://lsr1991.github.io/2016/01/03/kafka-consumer-group-management/) +- [Kafka--Consumer消费者](http://blog.xiaoxiaomo.com/2016/05/14/Kafka-Consumer%E6%B6%88%E8%B4%B9%E8%80%85/) +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- + diff --git a/markdown-file/Kibana-Base.md b/markdown-file/Kibana-Base.md new file mode 100644 index 00000000..45f85adc --- /dev/null +++ b/markdown-file/Kibana-Base.md @@ -0,0 +1,72 @@ +# kibana 知识 + +## 基础知识 + +- 官网文档: + +### 安装 Kibana + +- CentOS 7.4 +- 至少需要 500M 内存 +- 官网文档: +- 官网文档 CentOS: +- 添加 KEY:`rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch` +- 添加源:`vim /etc/yum.repos.d/kibana.repo` + +``` +[kibana-6.x] +name=Kibana repository for 6.x packages +baseurl=https://artifacts.elastic.co/packages/6.x/yum +gpgcheck=1 +gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch +enabled=1 +autorefresh=1 +type=rpm-md +``` + +- 开始安装:`yum install -y kibana`,预计文件有 200M 左右,国内网络安装可能会很慢,慢慢等 + - 安装完后会多了一个:kibana 用户和组 +- 启动和停止软件(默认是不启动的): + - 启动:`systemctl start kibana.service` + - 状态:`systemctl status kibana.service` + - 停止:`systemctl stop kibana.service` + - 重新启动:`systemctl restart kibana.service` +- 安装完成后,增加系统自启动: + - `/bin/systemctl daemon-reload` + - `/bin/systemctl enable kibana.service` + +#### RPM 安装后的一些配置位置说明 + +- 官网文档 CentOS: +- 配置文件的参数说明: +- kibana 安装后位置:`/usr/share/kibana` +- kibana 的配置文件:`/etc/kibana/kibana.yml` +- Log 位置:`/var/log/kibana/` +- 数据位置:`/var/lib/kibana` +- 插件位置:`/usr/share/kibana/plugins` + + +#### 配置 + +- 编辑配置文件:`vim /etc/kibana/kibana.yml` +- 默认只能 localhost 访问,修改成支持外网访问 + +``` +打开这个注释:#server.host: "localhost" +改为:server.host: "0.0.0.0" +``` + +- 然后你可以访问:`http://192.168.0.105:5601`,可以看到 kibana 的相关界面。 + - 1. Create index pattern + - 如果你 Elasticsearch 新创建了索引,kibana 是不会自动帮你匹配到的,所以要匹配新索引,这一步都要走 + - 2. Discover | 右上角筛选时间区间 + - 这一步非常重要,里面的 filter,图表等都是基于此时间区间的 +- 在 logstash 安装这一步,如果你刚刚有按着我说的去做一个 elasticsearch 索引,那你此时不会看到这样的提示:`Unable to fetch mapping. Do you have indices matching the pattern?` + - 此时你可以直接点击 `create` 统计 `logstash-*` 格式的索引结果,看到相关内容 + - 如果你知道你的索引名称的规则,比如我现在要统计 Tomcat 的相关索引,我的索引名称是:`tomcat-log-*`,则我输入这个,点击:create 即可。 + + +## 资料 + +- <> +- <> \ No newline at end of file diff --git a/markdown-file/Kubernetes-Install-And-Usage.md b/markdown-file/Kubernetes-Install-And-Usage.md new file mode 100644 index 00000000..af9a8e53 --- /dev/null +++ b/markdown-file/Kubernetes-Install-And-Usage.md @@ -0,0 +1,202 @@ + + +# Kubernetes 部署 + +## 环境说明 + +- CentOS 7.4 +- 购买自阿里云普通的 ECS 华南地区(如果你是购买美国地区的服务器,则直接使用 kubespray 原项目,那些镜像地址不用修改,其他照着文档即可) +- 所有机子都是干净的不需要先安装 Docker 等其他容器相关的东西 +- 建议还是用美国服务器,不然各种网络的坑 + +| 机器简称 | 内网 IP 地址 | 部署软件 | 系统环境 | 硬件配置 | +|---|---|---|---|---| +| 操作机 | 172.20.229.224 | ansible | CentOS 7.4 | 1 vCPU + 2 GB | +| node1 | 172.20.229.225 | master | CentOS 7.4 | 1 vCPU + 4 GB | +| node2 | 172.20.229.226 | worker | CentOS 7.4 | 1 vCPU + 4 GB | +| node3 | 172.20.229.227 | worker | CentOS 7.4 | 1 vCPU + 4 GB | + + +## 所有机子都需要的环境准备 + +- 关闭 SELinux + - 编辑配置文件:`vim /etc/selinux/config` + - 把 `SELINUX=enforcing` 改为 `SELINUX=disabled` + +所有节点关闭防火墙:`systemctl stop firewalld && systemctl disable firewalld` + +安装自己常用的一些组件(非必须):vim zsh zip unzip lrzsz git + + +## 安装过程 + +#### 操作机安装 ansible + +================================= +yum install -y epel-release +yum install -y python34 python34-pip python-pip python-netaddr ansible git +pip install --upgrade Jinja2 +yum install -y gcc libffi-devel python-devel openssl-devel +================================= + +操作机免密码登录到其他节点 + +如果还不懂可以具体看我的这篇文章:[]() +ssh-keygen +ssh-copy-id -i /root/.ssh/id_rsa.pub -p 22 root@172.20.229.225 +ssh-copy-id -i /root/.ssh/id_rsa.pub -p 22 root@172.20.229.226 +ssh-copy-id -i /root/.ssh/id_rsa.pub -p 22 root@172.20.229.227 + +测试下是否可以免登陆: +ssh -p 22 root@172.20.229.225 +ssh -p 22 root@172.20.229.226 +ssh -p 22 root@172.20.229.227 + +#### 修改 kubespray 项目配置 + +- kubespray 项目官网: + + +在本地机子上 + +git clone https://github.com/kubernetes-incubator/kubespray.git + +当前时间(2018-02)最新版本是:v2.4.0,所以我 checkout v2.4.0 的 tag + +用 IntelliJ IDEA 打开该项目,然后批量替换: + +- `gcr.io/` 替换成:`registry.cn-hangzhou.aliyuncs.com/` +- 因为 gcr.io 这个网站的本地址是:https://cloud.google.com/container-registry/,国内的环境当然就没资格上了,所以才要替换。 +- 但是需要注意的是,官网的这些镜像阿里云不一定有,所以稳妥点,你最好可以去阿里云检查下的:,或者是: + + + + + +====================================================== + + +cd /opt/kubespray && cp -rfp inventory/sample inventory/mycluster + + +修改:inventory/mycluster/hosts.ini +python3 contrib/inventory_builder/inventory.py 172.20.229.225 172.20.229.226 172.20.229.227 + +# Review and change parameters under ``inventory/mycluster/group_vars`` +cat inventory/mycluster/group_vars/all.yml +cat inventory/mycluster/group_vars/k8s-cluster.yml + +修改 /kubespray/inventory/mycluster/hosts.ini,改为如下内容: + +``` +node1 ansible_ssh_host=172.20.229.225 ansible_user=root ip=172.20.229.225 +node2 ansible_ssh_host=172.20.229.226 ansible_user=root ip=172.20.229.226 +node3 ansible_ssh_host=172.20.229.227 ansible_user=root ip=172.20.229.227 + +[kube-master] +node1 + +[etcd] +node1 + +[kube-node] +node2 +node3 + +[k8s-cluster:children] +kube-node +kube-master +``` + + +然后把这个项目压缩成 zip 上传到操作机的 /opt 根目录上,然后解压。 + +然后在操作机上执行:`cd /opt/kubespray && ansible-playbook -i inventory/mycluster/hosts.ini cluster.yml` +然后会开始输出一大堆执行任务的东西,等等吧,预计需要 20~60 分钟左右。 + +然后报错: + +``` +Thursday 08 February 2018 18:03:14 +0800 (0:00:00.038) 0:04:14.420 ***** +FAILED - RETRYING: container_download | Download containers if pull is required or told to always pull (all nodes) (4 retries left). +FAILED - RETRYING: container_download | Download containers if pull is required or told to always pull (all nodes) (4 retries left). +FAILED - RETRYING: container_download | Download containers if pull is required or told to always pull (all nodes) (4 retries left). +FAILED - RETRYING: container_download | Download containers if pull is required or told to always pull (all nodes) (3 retries left). +FAILED - RETRYING: container_download | Download containers if pull is required or told to always pull (all nodes) (3 retries left). +FAILED - RETRYING: container_download | Download containers if pull is required or told to always pull (all nodes) (3 retries left). +FAILED - RETRYING: container_download | Download containers if pull is required or told to always pull (all nodes) (2 retries left). +FAILED - RETRYING: container_download | Download containers if pull is required or told to always pull (all nodes) (2 retries left). +FAILED - RETRYING: container_download | Download containers if pull is required or told to always pull (all nodes) (2 retries left). +FAILED - RETRYING: container_download | Download containers if pull is required or told to always pull (all nodes) (1 retries left). +FAILED - RETRYING: container_download | Download containers if pull is required or told to always pull (all nodes) (1 retries left). +fatal: [node1]: FAILED! => {"attempts": 4, "changed": true, "cmd": ["/usr/bin/docker", "pull", "registry.cn-hangzhou.aliyuncs.com/google_containers/cluster-proportional-autoscaler-amd64:1.1.2"], "delta": "0:00:00.413852", "end": "2018-02-08 18:03:38.396245", "msg": "non-zero return code", "rc": 1, "start": "2018-02-08 18:03:37.982393", "stderr": "Error response from daemon: repository registry.cn-hangzhou.aliyuncs.com/google_containers/cluster-proportional-autoscaler-amd64 not found: does not exist or no pull access", "stderr_lines": ["Error response from daemon: repository registry.cn-hangzhou.aliyuncs.com/google_containers/cluster-proportional-autoscaler-amd64 not found: does not exist or no pull access"], "stdout": "", "stdout_lines": []} +FAILED - RETRYING: container_download | Download containers if pull is required or told to always pull (all nodes) (1 retries left). +fatal: [node3]: FAILED! => {"attempts": 4, "changed": true, "cmd": ["/usr/bin/docker", "pull", "registry.cn-hangzhou.aliyuncs.com/google_containers/cluster-proportional-autoscaler-amd64:1.1.2"], "delta": "0:00:00.421977", "end": "2018-02-08 18:03:42.334875", "msg": "non-zero return code", "rc": 1, "start": "2018-02-08 18:03:41.912898", "stderr": "Error response from daemon: repository registry.cn-hangzhou.aliyuncs.com/google_containers/cluster-proportional-autoscaler-amd64 not found: does not exist or no pull access", "stderr_lines": ["Error response from daemon: repository registry.cn-hangzhou.aliyuncs.com/google_containers/cluster-proportional-autoscaler-amd64 not found: does not exist or no pull access"], "stdout": "", "stdout_lines": []} +fatal: [node2]: FAILED! => {"attempts": 4, "changed": true, "cmd": ["/usr/bin/docker", "pull", "registry.cn-hangzhou.aliyuncs.com/google_containers/cluster-proportional-autoscaler-amd64:1.1.2"], "delta": "0:00:00.390301", "end": "2018-02-08 18:03:46.246213", "msg": "non-zero return code", "rc": 1, "start": "2018-02-08 18:03:45.855912", "stderr": "Error response from daemon: repository registry.cn-hangzhou.aliyuncs.com/google_containers/cluster-proportional-autoscaler-amd64 not found: does not exist or no pull access", "stderr_lines": ["Error response from daemon: repository registry.cn-hangzhou.aliyuncs.com/google_containers/cluster-proportional-autoscaler-amd64 not found: does not exist or no pull access"], "stdout": "", "stdout_lines": []} +``` + +说明这个镜像在阿里云没有,所以我有在 docker 官网找了下,有一个这个:`mirrorgooglecontainers/cluster-proportional-autoscaler-amd64` + +建议你可以找个有 docker 的服务器试一下:`docker pull mirrorgooglecontainers/cluster-proportional-autoscaler-amd64`,如果能下载,那就说明没问题了。 +同时也发现这个 docker hub 用户是北京的,应该同道。 + +然后又报了下面这个错误。主要是这个脚本:/usr/local/bin/etcd-scripts/make-ssl-etcd.sh 有这个错误:$'\r': command not found +而这个脚本是来自操作机上的 /opt/kubespray/roles/etcd/files 目录 + +``` +fatal: [node1 -> 172.20.229.225]: FAILED! => {"changed": true, "cmd": ["bash", "-x", "/usr/local/bin/etcd-scripts/make-ssl-etcd.sh", "-f", "/etc/ssl/etcd/openssl.conf", "-d", "/etc/ssl/etcd/ssl"], "delta": "0:00:00.012822", "end": "2018-02-08 18:42:09.815776", "msg": "non-zero return code", "rc": 2, "start": "2018-02-08 18:42:09.802954", "stderr": "+ $'\\r'\n/usr/local/bin/etcd-scripts/make-ssl-etcd.sh: line 2: $'\\r': command not found\n+ $'\\r'\n/usr/local/bin/etcd-scripts/make-ssl-etcd.sh: line 16: $'\\r': command not found\n+ set -o $'errexit\\r'\n/usr/local/bin/etcd-scripts/make-ssl-etcd.sh: line 17: set: errexit\r: invalid option name\n+ set -o $'pipefail\\r'\n/usr/local/bin/etcd-scripts/make-ssl-etcd.sh: line 18: set: pipefail\r: invalid option name\n/usr/local/bin/etcd-scripts/make-ssl-etcd.sh: line 19: syntax error near unexpected token `$'\\r''\n/usr/local/bin/etcd-scripts/make-ssl-etcd.sh: line 19: `usage()\r'", "stderr_lines": ["+ $'\\r'", "/usr/local/bin/etcd-scripts/make-ssl-etcd.sh: line 2: $'\\r': command not found", "+ $'\\r'", "/usr/local/bin/etcd-scripts/make-ssl-etcd.sh: line 16: $'\\r': command not found", "+ set -o $'errexit\\r'", "/usr/local/bin/etcd-scripts/make-ssl-etcd.sh: line 17: set: errexit", ": invalid option name", "+ set -o $'pipefail\\r'", "/usr/local/bin/etcd-scripts/make-ssl-etcd.sh: line 18: set: pipefail", ": invalid option name", "/usr/local/bin/etcd-scripts/make-ssl-etcd.sh: line 19: syntax error near unexpected token `$'\\r''", "/usr/local/bin/etcd-scripts/make-ssl-etcd.sh: line 19: `usage()", "'"], "stdout": "", "stdout_lines": []} +``` + +我们需要操作这个机节点做这样的操作: + +``` +yum install -y dos2unix unix2dos + +cd /opt/kubespray/roles/etcd/files && dos2unix make-ssl-etcd.sh +cd /opt/kubespray/roles/kubernetes/secrets/files && dos2unix make-ssl.sh +``` + + + + + + + +#### 验证 + +SSH 连上 master 节点:ssh root@172.20.229.225 +输入:`kubectl get nodes` + +展示出如下信息: +NAME STATUS AGE VERSION +node1 Ready,SchedulingDisabled 1m v1.6.1+coreos.0 +node2 Ready 1m v1.6.1+coreos.0 +node3 Ready 1m v1.6.1+coreos.0 + +## 资料 + +- +- +- <> +====================================================== + +安装bzip2软件 + +yum install -y bzip2 + +tar -xjvf k8s_images.tar.bz2 + +设置 hostname + +hostnamectl --static set-hostname k8s-master + +hostnamectl --static set-hostname k8s-node-1 + + +在master和slave的/etc/hosts文件中均加入以下内容: + +172.18.218.96 k8s-master +172.18.218.96 etcd +172.18.218.96 registry +172.18.218.97 k8s-node-1 + diff --git a/LDAP-Install-And-Settings.md b/markdown-file/LDAP-Install-And-Settings.md similarity index 98% rename from LDAP-Install-And-Settings.md rename to markdown-file/LDAP-Install-And-Settings.md index 9735cfb9..8dd0e95b 100644 --- a/LDAP-Install-And-Settings.md +++ b/markdown-file/LDAP-Install-And-Settings.md @@ -110,7 +110,7 @@ ou: Group - 重启下服务:`systemctl restart slapd` - 本机测试,输入命令:`ldapsearch -LLL -W -x -D "cn=gitnavi,dc=youmeek,dc=com" -H ldap://localhost -b "dc=youmeek,dc=com"`,输入 domain 密码,可以查询到相应信息 - 局域网客户端连接测试,下载 Ldap Admin(下载地址看文章下面),具体连接信息看下图: -- ![Ldap Admin](images/Ldap-Install-And-Settings-a-1.png) +- ![Ldap Admin](../images/Ldap-Install-And-Settings-a-1.png) ## LDAP 客户端 diff --git a/Linux.md b/markdown-file/Linux.md similarity index 100% rename from Linux.md rename to markdown-file/Linux.md diff --git a/Logstash-Base.md b/markdown-file/Logstash-Base.md similarity index 100% rename from Logstash-Base.md rename to markdown-file/Logstash-Base.md diff --git a/markdown-file/Maven-Install-And-Settings.md b/markdown-file/Maven-Install-And-Settings.md new file mode 100644 index 00000000..fa342b94 --- /dev/null +++ b/markdown-file/Maven-Install-And-Settings.md @@ -0,0 +1,98 @@ +# Maven 安装和配置 + +## Maven 资料 + +- 官网: +- 官网下载: +- 历史版本下载: +- 此时(20160208) Maven 最新版本为:**3.3.9** + +## Maven 安装(bash 环境) + +- Maven 3.3 的 JDK 最低要求是 JDK 7 +- 下载压缩包:`wget http://mirrors.cnnic.cn/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz` +- 解压:`tar zxvf apache-maven-3.3.9-bin.tar.gz` +- 修改目录名,默认的太长了:`mv apache-maven-3.3.9/ maven3.3.9/` +- 移到我个人习惯的安装目录下:`mv maven3.3.9/ /usr/local` +- 环境变量设置:`vim /etc/profile` +- 在文件最尾巴添加下面内容: + +``` ini +# Maven +MAVEN_HOME=/usr/local/maven3.3.9 +M3_HOME=/usr/local/maven3.3.9 +PATH=$PATH:$M3_HOME/bin +MAVEN_OPTS="-Xms256m -Xmx356m" +export M3_HOME +export MAVEN_HOME +export PATH +export MAVEN_OPTS +``` + +- 刷新配置文件:`source /etc/profile` +- 测试是否安装成功:`mvn -version` + +## Maven 配置 + +- 创建本地参数:`mkdir -p /opt/maven-repository` +- 配置项目连接上私服 +- 编辑配置文件:`vim /usr/local/maven3.3.9/conf/settings.xml` + +``` xml + + + + + + /opt/maven-repository + + + + + + + + + + + nexus-releases + admin + admin123 + + + nexus-snapshots + admin + admin123 + + + + + + + aliyun-releases + * + http://maven.aliyun.com/nexus/content/groups/public/ + + + aliyun-snapshots + * + http://maven.aliyun.com/nexus/content/groups/public/ + + + + +``` + + + + +## 资料 + +- +- +- +- +- +- +- +- \ No newline at end of file diff --git a/MongoDB-Install-And-Settings.md b/markdown-file/MongoDB-Install-And-Settings.md similarity index 85% rename from MongoDB-Install-And-Settings.md rename to markdown-file/MongoDB-Install-And-Settings.md index fba0cd17..f05e7b74 100644 --- a/MongoDB-Install-And-Settings.md +++ b/markdown-file/MongoDB-Install-And-Settings.md @@ -22,45 +22,93 @@ - 请查看介绍中支持哪个版本: - 目前 201712 支持 MongoDB 3.4 +------------------------------------------------------------------- -## Docker 下安装 MongoDB +## Docker 下安装 MongoDB(方式一) -- 先创建一个宿主机以后用来存放数据的目录:`mkdir -p /data/mongo/db` -- 安装镜像:`docker pull mongo:3.4` -- 查看下载下来的镜像:`docker images` -- 首次运行镜像:`docker run -p 27017:27017 -v /data/mongo/db:/data/db -d mongo:3.4` -- 查看容器运行情况:`docker ps` -- 进入容器中 mongo shell 交互界面:`docker exec -it 09747cd7d0bd mongo casdb` +- 先创建一个宿主机以后用来存放数据的目录:`mkdir -p /data/docker/mongo/db` +- 赋权:`chmod 777 -R /data/docker/mongo/db` +- 首次运行镜像:`docker run --name cloud-mongo -p 27017:27017 -v /data/docker/mongo/db:/data/db -d mongo:3.4` +- 进入容器中 mongo shell 交互界面:`docker exec -it cloud-mongo mongo adg_mongo_db` - 创建一个用户: ``` db.createUser( { - user: "casuser", - pwd: "casuser123456", + user: "adguser", + pwd: "adg123456", roles: [ - { role: "dbAdmin", db: "casdb" }, - { role: "readWrite", db: "casdb" } + { role: "dbAdmin", db: "adg_mongo_db" }, + { role: "readWrite", db: "adg_mongo_db" } ] } ) ``` -- 然后停掉容器:`docker stop 09747cd7d0bd` -- 重新运行镜像,这次增加需要授权才能访问的配置:`docker run -d -p 27017:27017 -v /data/mongo/db:/data/db --restart always --name cas-mongo mongo:3.4 --auth` -- 重新启动服务:`docker restart cas-mongo` +- 然后停掉容器:`docker stop cloud-mongo` +- 然后删除容器:`docker rm cloud-mongo` +- 重新运行镜像,这次增加需要授权才能访问的配置:`docker run -d -p 27017:27017 -v /data/docker/mongo/db:/data/db --restart always --name cloud-mongo mongo:3.4 --auth` +- 重新启动服务:`docker restart cloud-mongo` +- 导出:`docker exec -it cloud-mongo mongoexport -h 127.0.0.1 -u 用户名 -p 密码 -d 库名 -c 集合名 -o /data/db/mongodb.json --type json` +- 导入:`docker exec -it cloud-mongo mongoimport -h 127.0.0.1 -u 用户名 -p 密码 -d 库名 -c 集合名 --file /data/db/mongodb.json --type json` -## 安装环境 -- CentOS 6 +## Docker 下安装 MongoDB(方式二) -## MongoDB 安装 +- 先创建一个宿主机以后用来存放数据的目录:`mkdir -p /data/docker/mongo/db` +- 赋权:`chmod 777 -R /data/docker/mongo/db` +- 运行镜像:`docker run --name cloud-mongo2 -p 37017:27017 -v /data/docker/mongo/db:/data/db -d mongo:3.4 --auth` +- 进入容器中 mongo shell 交互界面:`docker exec -it cloud-mongo2 mongo` +- 创建一个超级用户: + +``` +use admin + +db.createUser( + { + user: "mongo-admin", + pwd: "123456", + roles: [ + { role: "root", db: "admin" } + ] + } +) + +db.auth("mongo-admin","123456") +``` + +- 使用 db.auth() 可以对数据库中的用户进行验证,如果验证成功则返回 1,否则返回 0 +- 接着创建一个普通数据库和用户: + +``` + +use my_test_db + + +db.createUser( + { + user: "mytestuser", + pwd: "123456", + roles: [ + { role: "dbAdmin", db: "my_test_db" }, + { role: "readWrite", db: "my_test_db" } + ] + } +) + + +db.auth("mytestuser","123456") +``` + +------------------------------------------------------------------- + +## MongoDB 传统方式安装 - 关闭 SELinux - 编辑配置文件:`vim /etc/selinux/config` - 把 `SELINUX=enforcing` 改为 `SELINUX=disabled` -- MongoDB 安装 +- MongoDB 资料 - 官网: - 官网文档: - 此时(20170228) 最新稳定版本为:**3.4.2** @@ -243,9 +291,6 @@ auth=true - 卸载命令:`yum erase $(rpm -qa | grep mongodb-org)` - 删除数据库:`rm -r /var/lib/mongo` - 删除 log:`rm -r /var/log/mongodb` -- 数据的导出、导入 - - 导出:`mongoexport -h 127.0.0.1 -u 用户名 -p 密码 -d 库名 -c 集合名 -o /opt/mongodb.json --type json` - - 导入:`mongoimport -h 127.0.0.1 -u 用户名 -p 密码 -d 库名 -c 集合名 --file /opt/mongodb.json --type json` ## 添加授权用户 @@ -348,6 +393,12 @@ $ne ->not equal 不等于 - - +## 导入 / 导出 / 备份 /还原 + +- 数据的导出、导入 + - 导出:`mongoexport -h 127.0.0.1 -u 用户名 -p 密码 -d 库名 -c 集合名 -o /opt/mongodb.json --type json` + - 导入:`mongoimport -h 127.0.0.1 -u 用户名 -p 密码 -d 库名 -c 集合名 --file /opt/mongodb.json --type json` + ## Java 包 @@ -359,6 +410,15 @@ $ne ->not equal 不等于 - Robomongo: +## 基准测试 + +- + +## 随机生成测试数据 + +- + + ## 资料 - diff --git a/markdown-file/Mycat-Install-And-Settings.md b/markdown-file/Mycat-Install-And-Settings.md new file mode 100644 index 00000000..3ea1ab01 --- /dev/null +++ b/markdown-file/Mycat-Install-And-Settings.md @@ -0,0 +1,1225 @@ +# Mycat 安装和配置 + + +## 部署的环境 + +- 系统:CentOS 6.7 / CentOS 7.4 +- JDK:jdk-8u72-linux-x64.tar.gz +- Mycat:Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz +- 推荐测试机子配置:1 CPU + 2 GB RAM + Docker + +## Docker 快速部署 MySQL + +``` +docker run --name mysql1 -p 3316:3306 -e MYSQL_ROOT_PASSWORD=root -d daocloud.io/library/mysql:5.7.13 +docker run --name mysql2 -p 3326:3306 -e MYSQL_ROOT_PASSWORD=root -d daocloud.io/library/mysql:5.7.13 +docker run --name mysql3 -p 3336:3306 -e MYSQL_ROOT_PASSWORD=root -d daocloud.io/library/mysql:5.7.13 +``` + +## Mycat 安装 + +- 官网(页头有一个 PDF 要记得下载,这本资料写得很好): +- 官网下载(官网下载地址很乱,如果哪天右边这个地址不行了,到官网加群问下吧): +- 项目 Github: +- 此时(20170122) 最新稳定版本为:**1.6**,下载下来的文件名称:**Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz** +- 安装前的准备: + - 这台机子必须装有 JDK,并且配置好 JAVA_HOME。JDK 的安装看: +- 开始安装: + - 假设 Mycat 安装包的完整路径是:**/opt/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz** + - 解压:`cd /opt ; tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz` + - 移动解压的目录到官方建议的目录下:`mv /opt/mycat /usr/local/` + - 设置 Mycat 的环境变量 + - `vim /etc/profile`,添加如下内容: + +``` nginx +export MYCAT_HOME=/usr/local/mycat +export PATH=$PATH:$MYCAT_HOME/bin +``` + +- 刷新配置:`source /etc/profile` +- 到这里就安装好了,但是先不启动,需要先去配置相应的配置文件。 + +## Mycat 只分库配置,并且要可预期租户数量(没有分表、读写分离、高可用) + +- 请至少预留 512M 内存给 Mycat +- 使用 Mycat 这几个配置文件必定会改动到。这一个文件所代表的含义几句话说不了,还请你自己看下官网的文档,在目录:conf 下 + +#### server.xml 配置详解 + +- `server.xml`,主要用于配置系统变量、用户管理、用户权限等。 +- **默认配置中有一个 TESTDB 相关的数据库用户配置,都要自己手工去掉。建议可以把配置文件中 TESTDB 相关的单词都替换成你的数据库名称(你最好能读懂各个配置)。** +- 配置用户,添加下面内容: + +```xml + + + 123456 + + adg_system + + false + + 0 + + 0 + + + + +``` + +- mycat 中间件的全局配置: + +```xml + + 0 + 0 + + 2 + + + + + + + + + + + + + 0 + + + + + + + + + 0 + + + 1 + + + 1m + + + 1k + + 0 + + + 384m + + + + false + + + +``` + +#### schema.xml 配置详解 + + +- `schema.xml`,用于设置 Mycat 的逻辑库、表、数据节点、dataHost 等内容,分库分表、读写分离等等都是在这里进行配置的 +- schema.xml 中特别注意的是分片节点的配置。如下,其中 adg_system_0000,adg_system_0001,adg_system_0002 是需要我们自己在 mysql 对应的机子上人工创建这三个空白数据库和表。 + +```xml + + + + + + + + + + + +
+
+ + + + + + + +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select user() + + + + + select user() + + + + + select user() + + + + + +
+``` + +#### 如果节点数据很多的情况,我们有一种简便写法 + +```xml + + + + + + + + + + +
+ + + +
+
+ + + + + + + + + select user() + + + + + +
+``` + + +#### rule.xml 配置详解 + +- `rule.xml`,设置分片规则。 +- 下面我设置一个根据店铺进行分片的规格: + +```xml + + + + + + + + id + func1 + + + + + + user_id + func1 + + + + + + sharding_id + hash-int + + + + + id + rang-long + + + + + id + mod-long + + + + + id + murmur + + + + + id + crc32slot + + + + + create_time + partbymonth + + + + + calldate + latestMonth + + + + + + id + rang-mod + + + + + + id + jump-consistent-hash + + + + + + + + shop_id + by-shop-id + + + + + + sharding-by-shop-id.txt + 1 + 0 + + + + + + + 0 + 2 + 160 + + + + + + 2 + + + + partition-hash-int.txt + + + + autopartition-long.txt + + + + 3 + + + + 8 + 128 + + + + 24 + + + + yyyy-MM-dd + 2015-01-01 + + + + partition-range-mod.txt + + + + 3 + + + +``` + +- 还需要在 conf 新增文件 sharding-by-shop-id.txt 文件,内容是: +- 需要注意的是: + +``` +417454619141211000=0 +417454619141211001=1 +417454619141211002=2 +``` + +- 表示 shop_id 为 417454619141211000 的时候,用 adg_system_0000 库 +- 表示 shop_id 为 417454619141211001 的时候,用 adg_system_0001 库 +- 表示 shop_id 为 417454619141211002 的时候,用 adg_system_0002 库 +- 其中第一个库是从下表 0 开始的。 + +#### log4j2.xml 配置详解 + + +- `log4j2.xml`,用于设置 Mycat 的日志输出规则,默认日志文件是输出 mycat 根目录下的 logs 目录下。 + + +## 只分库的 demo 脚本 + +- 在 MySQL 实例 1 中执行如下初始化脚本: + +```sql +CREATE DATABASE /*!32312 IF NOT EXISTS*/`adg_system_0000` /*!40100 DEFAULT CHARACTER SET utf8mb4 */; +USE `adg_system_0000`; +``` + +- 在 MySQL 实例 2 中执行如下初始化脚本: + +```sql +CREATE DATABASE /*!32312 IF NOT EXISTS*/`adg_system_0001` /*!40100 DEFAULT CHARACTER SET utf8mb4 */; +USE `adg_system_0001`; +``` + +- 在 MySQL 实例 3 中执行如下初始化脚本: + +```sql +CREATE DATABASE /*!32312 IF NOT EXISTS*/`adg_system_0002` /*!40100 DEFAULT CHARACTER SET utf8mb4 */; +USE `adg_system_0002`; +``` + +## 其他设置 + +- 假设你上面的配置文件都配置好了: + - 开放 8066 端口 + - 如果只是临时测试,可以临时关掉防火墙:`service iptables stop` + - 不然就添加防火墙规则: + - 添加规则:`sudo iptables -I INPUT -p tcp -m tcp --dport 8066 -j ACCEPT` + - 保存规则:`sudo service iptables save` + - 重启 iptables:`sudo service iptables restart` +- 启动/停止/重启 + - **注意:在启动之前请一定要确保你可以用 mysql 工具连上你们的三个 mysql 和对应的数据库。有时候你连得上 mysql,但是你的账号不一定能连上这个 mysql 对应的数据库。** + - 启动有两种,一种是后台启动,启动后看不到任何信息。一种是控制台启动,启动后进入 Mycat 的控制台界面,显示当前 Mycat 的活动信息,按 Ctrl + C 停止控制台的时候 Mycat 也跟着停止。 + - 进入 Mycat 目录:`cd /usr/local/mycat/bin` + - 后台启动:`./mycat start && tail -300f /usr/local/mycat/logs/mycat.log` + - 控制台启动:`./mycat console` + - 重启:`./mycat restart` + - 停止:`./mycat stop` +- 连接 Mycat + - 连接 Mycat 的过程跟连接普通的 MySQL 表面上是没啥区别的,使用的命令都是一个样。但是需要注意的是,很容易出问题。对连接客户端有各种意外,目前我做了总结: + - 连接命令:`mysql -h192.168.1.112 -uroot -p -P8066`,然后输入 mycat 的 root 用户密码(在上面介绍的 server.xml 中配置的) + - **不建议** 的连接方式: + - SQLyog 软件,我这边是报:*find no Route:select * from `youmeek_nav`.`nav_url` limit 0, 1000* + - Windows 系统下使用 cmd 去连接,我这边是报:*ERROR 1105 (HY000): Unknown character set: 'gbk'* + - MySQL-Front 软件,没用过,但是别人说是有兼容性问题 + - **建议** 的连接方式: + - Navicat for mysql 软件 + - Linux 下的 MySQL 客户端命令行 + +## 使用 Navicat 连接 MyCat 测试 SQL + + +#### 创建表 SQL + +```sql + +CREATE TABLE `adg_ads` ( + `ads_id` BIGINT(20) NOT NULL COMMENT '广告表ID', + `ads_set_id` BIGINT(20) NOT NULL COMMENT '广告组表ID', + `ads_title` VARCHAR(32) NOT NULL COMMENT '广告标题', + `shop_id` BIGINT(20) NOT NULL COMMENT '店铺ID', + `channel_id` BIGINT(20) NOT NULL COMMENT '渠道ID', + `shop_name` VARCHAR(32) NOT NULL COMMENT '店铺名称', + `channel_name` VARCHAR(32) NOT NULL COMMENT '渠道名称', + PRIMARY KEY (`ads_id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='广告表'; + + +CREATE TABLE `adg_ads_set` ( + `ads_set_id` BIGINT(20) NOT NULL COMMENT '广告组表ID', + `ads_set_title` VARCHAR(32) NOT NULL COMMENT '广告组标题', + `ads_campaign_id` BIGINT(20) NOT NULL COMMENT '广告系列表ID', + `shop_id` BIGINT(20) NOT NULL COMMENT '店铺ID', + `channel_id` BIGINT(20) NOT NULL COMMENT '渠道ID', + `shop_name` VARCHAR(32) NOT NULL COMMENT '店铺名称', + `channel_name` VARCHAR(32) NOT NULL COMMENT '渠道名称', + PRIMARY KEY (`ads_set_id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='广告组表'; + + +CREATE TABLE `adg_ads_campaign` ( + `ads_campaign_id` BIGINT(20) NOT NULL COMMENT '广告系列表ID', + `ads_campaign_title` VARCHAR(32) NOT NULL COMMENT '广告系列标题', + `shop_id` BIGINT(20) NOT NULL COMMENT '店铺ID', + `channel_id` BIGINT(20) NOT NULL COMMENT '渠道ID', + `shop_name` VARCHAR(32) NOT NULL COMMENT '店铺名称', + `channel_name` VARCHAR(32) NOT NULL COMMENT '渠道名称', + PRIMARY KEY (`ads_campaign_id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='广告系列表'; + + +CREATE TABLE `adg_channel` ( + `channel_id` BIGINT(20) NOT NULL COMMENT '渠道ID', + `channel_name` VARCHAR(32) NOT NULL COMMENT '渠道名称', + PRIMARY KEY (`channel_id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='渠道表'; + + +CREATE TABLE `adg_shop` ( + `shop_id` BIGINT(20) NOT NULL COMMENT '店铺ID', + `shop_name` VARCHAR(32) NOT NULL COMMENT '店铺名称', + PRIMARY KEY (`shop_id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='商品表'; + + +CREATE TABLE `adg_shop_channel` ( + `shop_channel_id` BIGINT(20) NOT NULL COMMENT '店铺渠道中间表ID', + `shop_id` BIGINT(20) NOT NULL COMMENT '店铺ID', + `channel_id` BIGINT(20) NOT NULL COMMENT '渠道ID', + `shop_name` VARCHAR(32) NOT NULL COMMENT '店铺名称', + `channel_name` VARCHAR(32) NOT NULL COMMENT '渠道名称', + PRIMARY KEY (`shop_channel_id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='店铺渠道中间表'; +``` + +#### 创建数据 SQL + +```sql +INSERT INTO `adg_shop`(`shop_id`,`shop_name`) VALUES (417454619141211000,'NC站'); +INSERT INTO `adg_shop`(`shop_id`,`shop_name`) VALUES (417454619141211001,'BG站'); + +INSERT INTO `adg_channel`(`channel_id`,`channel_name`) VALUES (1,'Facebook'); +INSERT INTO `adg_channel`(`channel_id`,`channel_name`) VALUES (2,'Google'); +INSERT INTO `adg_channel`(`channel_id`,`channel_name`) VALUES (3,'Twitter'); + +INSERT INTO `adg_shop_channel`(`shop_channel_id`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (1,417454619141211000,1,'NC站','Facebook'); +INSERT INTO `adg_shop_channel`(`shop_channel_id`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (2,417454619141211000,2,'NC站','Google'); +INSERT INTO `adg_shop_channel`(`shop_channel_id`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (3,417454619141211001,1,'BG站','Facebook'); +INSERT INTO `adg_shop_channel`(`shop_channel_id`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (4,417454619141211001,2,'BG站','Google'); + +INSERT INTO `adg_ads_campaign`(`ads_campaign_id`,`ads_campaign_title`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (1,'第1个广告系列',417454619141211000,1,'NC站','Facebook'); +INSERT INTO `adg_ads_campaign`(`ads_campaign_id`,`ads_campaign_title`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (2,'第2个广告系列',417454619141211001,2,'BG站','Google'); + +INSERT INTO `adg_ads_set`(`ads_set_id`,`ads_set_title`,`ads_campaign_id`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (1,'第1个广告集',1,417454619141211000,1,'NC站','Facebook'); +INSERT INTO `adg_ads_set`(`ads_set_id`,`ads_set_title`,`ads_campaign_id`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (2,'第2个广告集',2,417454619141211001,2,'BG站','Google'); + +INSERT INTO `adg_ads`(`ads_id`,`ads_set_id`,`ads_title`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (1,1,'第1个广告',417454619141211000,1,'NC站','Facebook'); +INSERT INTO `adg_ads`(`ads_id`,`ads_set_id`,`ads_title`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (2,2,'第2个广告',417454619141211001,2,'BG站','Google'); +``` + + +## mycat 正常启动的 log 内容 + +- `tail -300f wrapper.log` + +```log +2018-02-05 14:15:41.432 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDBPool.(PhysicalDBPool.java:100)) - total resouces of dataHost mysql_host_0 is :1 +2018-02-05 14:15:41.435 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDBPool.(PhysicalDBPool.java:100)) - total resouces of dataHost mysql_host_2 is :1 +2018-02-05 14:15:41.435 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDBPool.(PhysicalDBPool.java:100)) - total resouces of dataHost mysql_host_1 is :1 +2018-02-05 14:15:41.442 INFO [WrapperSimpleAppMain] (io.mycat.cache.CacheService.createLayeredPool(CacheService.java:125)) - create layer cache pool TableID2DataNodeCache of type encache ,default cache size 10000 ,default expire seconds18000 +2018-02-05 14:15:41.445 INFO [WrapperSimpleAppMain] (io.mycat.cache.DefaultLayedCachePool.createChildCache(DefaultLayedCachePool.java:80)) - create child Cache: TESTDB_ORDERS for layered cache TableID2DataNodeCache, size 50000, expire seconds 18000 +2018-02-05 14:15:41.597 INFO [WrapperSimpleAppMain] (io.mycat.config.classloader.DynaClassLoader.(DynaClassLoader.java:34)) - dyna class load from ./catlet,and auto check for class file modified every 60 seconds +2018-02-05 14:15:41.601 INFO [WrapperSimpleAppMain] (io.mycat.MycatServer.startup(MycatServer.java:266)) - =============================================== +2018-02-05 14:15:41.602 INFO [WrapperSimpleAppMain] (io.mycat.MycatServer.startup(MycatServer.java:267)) - MyCat is ready to startup ... +2018-02-05 14:15:41.602 INFO [WrapperSimpleAppMain] (io.mycat.MycatServer.startup(MycatServer.java:279)) - Startup processors ...,total processors:1,aio thread pool size:4 each process allocated socket buffer pool bytes ,a page size:2097152 a page's chunk number(PageSize/ChunkSize) is:512 buffer page's number is:20 +2018-02-05 14:15:41.602 INFO [WrapperSimpleAppMain] (io.mycat.MycatServer.startup(MycatServer.java:280)) - sysconfig params:SystemConfig [processorBufferLocalPercent=100, frontSocketSoRcvbuf=1048576, frontSocketSoSndbuf=4194304, backSocketSoRcvbuf=4194304, backSocketSoSndbuf=1048576, frontSocketNoDelay=1, backSocketNoDelay=1, maxStringLiteralLength=65535, frontWriteQueueSize=2048, bindIp=0.0.0.0, serverPort=8066, managerPort=9066, charset=utf8mb4, processors=1, processorExecutor=4, timerExecutor=2, managerExecutor=2, idleTimeout=1800000, catletClassCheckSeconds=60, sqlExecuteTimeout=300, processorCheckPeriod=1000, dataNodeIdleCheckPeriod=300000, dataNodeHeartbeatPeriod=10000, clusterHeartbeatUser=_HEARTBEAT_USER_, clusterHeartbeatPass=_HEARTBEAT_PASS_, clusterHeartbeatPeriod=5000, clusterHeartbeatTimeout=10000, clusterHeartbeatRetry=10, txIsolation=3, parserCommentVersion=50148, sqlRecordCount=10, bufferPoolPageSize=2097152, bufferPoolChunkSize=4096, bufferPoolPageNumber=20, maxResultSet=524288, bigResultSizeSqlCount=10, bufferUsagePercent=80, flowControlRejectStrategy=0, clearBigSqLResultSetMapMs=600000, defaultMaxLimit=100, sequnceHandlerType=2, sqlInterceptor=io.mycat.server.interceptor.impl.DefaultSqlInterceptor, sqlInterceptorType=select, sqlInterceptorFile=/usr/local/mycat/logs/sql.txt, mutiNodeLimitType=0, mutiNodePatchSize=100, defaultSqlParser=druidparser, usingAIO=0, packetHeaderSize=4, maxPacketSize=16777216, mycatNodeId=1] +2018-02-05 14:15:41.667 INFO [WrapperSimpleAppMain] (io.mycat.MycatServer.startup(MycatServer.java:381)) - using nio network handler +2018-02-05 14:15:41.681 INFO [WrapperSimpleAppMain] (io.mycat.MycatServer.startup(MycatServer.java:397)) - $_MyCatManager is started and listening on 9066 +2018-02-05 14:15:41.682 INFO [WrapperSimpleAppMain] (io.mycat.MycatServer.startup(MycatServer.java:401)) - $_MyCatServer is started and listening on 8066 +2018-02-05 14:15:41.682 INFO [WrapperSimpleAppMain] (io.mycat.MycatServer.startup(MycatServer.java:403)) - =============================================== +2018-02-05 14:15:41.682 INFO [WrapperSimpleAppMain] (io.mycat.MycatServer.startup(MycatServer.java:407)) - Initialize dataHost ... +2018-02-05 14:15:41.682 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDBPool.initSource(PhysicalDBPool.java:294)) - init backend myqsl source ,create connections total 10 for hostM1 index :0 +2018-02-05 14:15:41.683 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0000 +2018-02-05 14:15:41.686 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0000 +2018-02-05 14:15:41.686 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0000 +2018-02-05 14:15:41.689 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0000 +2018-02-05 14:15:41.690 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0000 +2018-02-05 14:15:41.690 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0000 +2018-02-05 14:15:41.690 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0000 +2018-02-05 14:15:41.690 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0000 +2018-02-05 14:15:41.690 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0000 +2018-02-05 14:15:41.690 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0000 +2018-02-05 14:15:41.834 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=1, lastTime=1517811341834, user=root, schema=adg_system_0000, old shema=adg_system_0000, borrowed=true, fromSlaveDB=false, threadId=793, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3316, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:41.835 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=2, lastTime=1517811341835, user=root, schema=adg_system_0000, old shema=adg_system_0000, borrowed=true, fromSlaveDB=false, threadId=797, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3316, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:41.835 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=4, lastTime=1517811341835, user=root, schema=adg_system_0000, old shema=adg_system_0000, borrowed=true, fromSlaveDB=false, threadId=795, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3316, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:41.836 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=8, lastTime=1517811341836, user=root, schema=adg_system_0000, old shema=adg_system_0000, borrowed=true, fromSlaveDB=false, threadId=796, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3316, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:41.836 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=7, lastTime=1517811341836, user=root, schema=adg_system_0000, old shema=adg_system_0000, borrowed=true, fromSlaveDB=false, threadId=794, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3316, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:41.837 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=3, lastTime=1517811341837, user=root, schema=adg_system_0000, old shema=adg_system_0000, borrowed=true, fromSlaveDB=false, threadId=801, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3316, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:41.837 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=5, lastTime=1517811341837, user=root, schema=adg_system_0000, old shema=adg_system_0000, borrowed=true, fromSlaveDB=false, threadId=798, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3316, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:41.838 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=6, lastTime=1517811341838, user=root, schema=adg_system_0000, old shema=adg_system_0000, borrowed=true, fromSlaveDB=false, threadId=799, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3316, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:41.840 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=10, lastTime=1517811341840, user=root, schema=adg_system_0000, old shema=adg_system_0000, borrowed=true, fromSlaveDB=false, threadId=800, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3316, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:41.842 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=9, lastTime=1517811341842, user=root, schema=adg_system_0000, old shema=adg_system_0000, borrowed=true, fromSlaveDB=false, threadId=802, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3316, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:41.899 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDBPool.initSource(PhysicalDBPool.java:319)) - init result :finished 10 success 10 target count:10 +2018-02-05 14:15:41.899 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDBPool.init(PhysicalDBPool.java:265)) - mysql_host_0 index:0 init success +2018-02-05 14:15:41.899 INFO [WrapperSimpleAppMain] (io.mycat.MycatServer.saveDataHostIndex(MycatServer.java:604)) - save DataHost index mysql_host_0 cur index 0 +2018-02-05 14:15:41.907 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDBPool.initSource(PhysicalDBPool.java:294)) - init backend myqsl source ,create connections total 10 for hostM1 index :0 +2018-02-05 14:15:41.907 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0002 +2018-02-05 14:15:41.908 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0002 +2018-02-05 14:15:41.908 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0002 +2018-02-05 14:15:41.909 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0002 +2018-02-05 14:15:41.912 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0002 +2018-02-05 14:15:41.915 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0002 +2018-02-05 14:15:41.916 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0002 +2018-02-05 14:15:41.916 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0002 +2018-02-05 14:15:41.916 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0002 +2018-02-05 14:15:41.917 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0002 +2018-02-05 14:15:42.021 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=12, lastTime=1517811342021, user=root, schema=adg_system_0002, old shema=adg_system_0002, borrowed=true, fromSlaveDB=false, threadId=779, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3336, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.023 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=11, lastTime=1517811342022, user=root, schema=adg_system_0002, old shema=adg_system_0002, borrowed=true, fromSlaveDB=false, threadId=780, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3336, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.027 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=13, lastTime=1517811342027, user=root, schema=adg_system_0002, old shema=adg_system_0002, borrowed=true, fromSlaveDB=false, threadId=781, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3336, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.027 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=14, lastTime=1517811342027, user=root, schema=adg_system_0002, old shema=adg_system_0002, borrowed=true, fromSlaveDB=false, threadId=782, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3336, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.030 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=17, lastTime=1517811342030, user=root, schema=adg_system_0002, old shema=adg_system_0002, borrowed=true, fromSlaveDB=false, threadId=783, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3336, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.032 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=16, lastTime=1517811342032, user=root, schema=adg_system_0002, old shema=adg_system_0002, borrowed=true, fromSlaveDB=false, threadId=785, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3336, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.034 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=15, lastTime=1517811342034, user=root, schema=adg_system_0002, old shema=adg_system_0002, borrowed=true, fromSlaveDB=false, threadId=784, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3336, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.036 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=18, lastTime=1517811342036, user=root, schema=adg_system_0002, old shema=adg_system_0002, borrowed=true, fromSlaveDB=false, threadId=786, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3336, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.043 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=19, lastTime=1517811342043, user=root, schema=adg_system_0002, old shema=adg_system_0002, borrowed=true, fromSlaveDB=false, threadId=787, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3336, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.043 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=20, lastTime=1517811342043, user=root, schema=adg_system_0002, old shema=adg_system_0002, borrowed=true, fromSlaveDB=false, threadId=788, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3336, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.118 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDBPool.initSource(PhysicalDBPool.java:319)) - init result :finished 10 success 10 target count:10 +2018-02-05 14:15:42.118 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDBPool.init(PhysicalDBPool.java:265)) - mysql_host_2 index:0 init success +2018-02-05 14:15:42.118 INFO [WrapperSimpleAppMain] (io.mycat.MycatServer.saveDataHostIndex(MycatServer.java:604)) - save DataHost index mysql_host_2 cur index 0 +2018-02-05 14:15:42.118 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDBPool.initSource(PhysicalDBPool.java:294)) - init backend myqsl source ,create connections total 10 for hostM1 index :0 +2018-02-05 14:15:42.119 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0001 +2018-02-05 14:15:42.120 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0001 +2018-02-05 14:15:42.120 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0001 +2018-02-05 14:15:42.121 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0001 +2018-02-05 14:15:42.121 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0001 +2018-02-05 14:15:42.122 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0001 +2018-02-05 14:15:42.122 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0001 +2018-02-05 14:15:42.122 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0001 +2018-02-05 14:15:42.123 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0001 +2018-02-05 14:15:42.123 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDatasource.getConnection(PhysicalDatasource.java:413)) - no ilde connection in pool,create new connection for hostM1 of schema adg_system_0001 +2018-02-05 14:15:42.235 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=21, lastTime=1517811342235, user=root, schema=adg_system_0001, old shema=adg_system_0001, borrowed=true, fromSlaveDB=false, threadId=776, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3326, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.237 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=23, lastTime=1517811342237, user=root, schema=adg_system_0001, old shema=adg_system_0001, borrowed=true, fromSlaveDB=false, threadId=777, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3326, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.239 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=26, lastTime=1517811342239, user=root, schema=adg_system_0001, old shema=adg_system_0001, borrowed=true, fromSlaveDB=false, threadId=781, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3326, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.240 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=22, lastTime=1517811342240, user=root, schema=adg_system_0001, old shema=adg_system_0001, borrowed=true, fromSlaveDB=false, threadId=778, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3326, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.243 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=25, lastTime=1517811342243, user=root, schema=adg_system_0001, old shema=adg_system_0001, borrowed=true, fromSlaveDB=false, threadId=779, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3326, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.245 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=24, lastTime=1517811342245, user=root, schema=adg_system_0001, old shema=adg_system_0001, borrowed=true, fromSlaveDB=false, threadId=780, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3326, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.249 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=29, lastTime=1517811342249, user=root, schema=adg_system_0001, old shema=adg_system_0001, borrowed=true, fromSlaveDB=false, threadId=782, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3326, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.249 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=30, lastTime=1517811342249, user=root, schema=adg_system_0001, old shema=adg_system_0001, borrowed=true, fromSlaveDB=false, threadId=783, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3326, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.250 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=28, lastTime=1517811342250, user=root, schema=adg_system_0001, old shema=adg_system_0001, borrowed=true, fromSlaveDB=false, threadId=785, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3326, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.251 INFO [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.handler.GetConnectionHandler.connectionAcquired(GetConnectionHandler.java:67)) - connected successfuly MySQLConnection [id=27, lastTime=1517811342251, user=root, schema=adg_system_0001, old shema=adg_system_0001, borrowed=true, fromSlaveDB=false, threadId=784, charset=latin1, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=116.196.111.68, port=3326, statusSync=null, writeQueue=0, modifiedSQLExecuted=false] +2018-02-05 14:15:42.324 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDBPool.initSource(PhysicalDBPool.java:319)) - init result :finished 10 success 10 target count:10 +2018-02-05 14:15:42.324 INFO [WrapperSimpleAppMain] (io.mycat.backend.datasource.PhysicalDBPool.init(PhysicalDBPool.java:265)) - mysql_host_1 index:0 init success +2018-02-05 14:15:42.324 INFO [WrapperSimpleAppMain] (io.mycat.MycatServer.saveDataHostIndex(MycatServer.java:604)) - save DataHost index mysql_host_1 cur index 0 +``` + +## 使用细节 + +- 声明: + - mycat 的库表这里我们称作虚拟库表 +- 创建新表流程: + - 先编辑 /conf/schema.xml 文件,增加对应的表信息 + - 把创建表 SQL 放在虚拟库上执行,则各个节点的物理库表会增加对应的表结构 + +------------------------------------------------------------------------------ + +## 只垂直分库流程 + +- 垂直切分缺点 + - 如果不采用全局表那就只能通过 API 接口关联表数据(为了增加吞吐,可以考虑多线程并发执行 API 接口后整合) + - 对于访问频繁、数据大的表,性能瓶颈依旧会存在 +- 这里只是写个大体思路,基础知识上面已经说了。 +- 假设以电商系统为例,拆分出:商品库、用户库、订单库,有 3 个 MySQL 实例各自存储一个业务库 +- 1. 因为不进行水平切分,所以不需要修改 rule.xml +- 2. 修改 server.xml,增加用户和权限 +- 3. 修改 schema.xml,增加逻辑库配置 + - dataHost 配置 3 个(只有 3 个 MySQL 实例) + - dataNode 配置 3 个,分别对应:商品库(1 个)、用户库(1 个)、订单库(1 个) + - schema 配置: + +``` + + + + +
+ + + +
+
+
+ +
+
+ +
+
+ + + +``` + +------------------------------------------------------------------------------ + +## 垂直分库基础上进行水平切分 + +- 水平分片原则 + - 能不切分是最好的,能用归档方式分开存储,分开查询的尽可能通过产品思维层面解决 + - 一般只推荐那些数据量大,并且读写频繁的表进行切分 + - 选择合适的切分规则、分片键 + - 尽可能避免跨分片 JOIN 操作 +- 水平分片的步骤 + - 选择分片键和分片算法 + - 一般分片键推荐的是查询条件基本都会带上的那个字段,或者影响面很广的字段 + - 分片键是能尽可能均匀把数据分片到各个节点 + - 没有什么可以选择的时候,推荐就是主键 + - MyCAT 配置分片节点 + - 测试分片节点 + - 业务数据迁移 + +#### 对订单相关业务进行水平切分 + +- 一般选择订单号或者所属用户 ID 进行分片,这里推荐使用所属用户 ID,因为查询订单信息基本都是从用户角度发起的 +- 1. 前面垂直分库已经修改 server.xml,这里不需要 +- 2. 修改 rule.xml,修改分片规则 + +``` + + + user_id + by-user-id-to-order + + + + + + 3 + +``` + +- 3. 修改 schema.xml,增加逻辑库配置 + - dataHost 配置 3 个(只有 3 个 MySQL 实例) + - dataNode 配置 5 个,分别对应:商品库(1 个)、用户库(1 个)、订单库(3 个) + - schema 配置,这里使用取模分片算法: + +``` + + + +
+
+ + + +
+
+
+ +
+
+ +
+ +
+ + +
+``` + +------------------------------------------------------------------------------ + +## 其他常用配置 + +#### SQL 拦截(做审计,不分该 SQL 是否执行成功与否) + +- 修改 server.xml(只拦截 UPDATE,DELETE,INSERT) + +``` +io.mycat.server.interceptor.impl.StatisticsSqlInterceptor +UPDATE,DELETE,INSERT +/opt/mycat-log.txt +``` + +#### SQL 防火墙 + +- 作用 + - 限制某些用户只能通过某些主机访问(whitehost 标签) + - 屏蔽一些 SQL 语句(blacklist 标签) + +``` + + + + + + + + true + + +``` + + +------------------------------------------------------------------------------ + +## 高可用方案(MySQL + MyCAT + Zookeeper + HAProxy + Keepalived) + +#### MySQL(3 节点) + +- 端口使用: + - 3406 + - 3407 + - 3408 + +``` +docker run -p 3406:3306 --name mycat-mysql-1 -e MYSQL_ROOT_PASSWORD=adgADG123456 -d mysql:5.7 + +docker run -p 3407:3306 --name mycat-mysql-2 -e MYSQL_ROOT_PASSWORD=adgADG123456 -d mysql:5.7 + +docker run -p 3408:3306 --name mycat-mysql-3 -e MYSQL_ROOT_PASSWORD=adgADG123456 -d mysql:5.7 +``` + + + +#### MyCAT + Zookeeper + +###### Zookeeper 单机多个实例(集群) + +- 端口使用: + - 2281 + - 2282 + - 2283 + +- 创建 docker compose 文件:`vim zookeeper.yml` +- 下面内容来自官网仓库: + +``` +version: '3.1' + +services: + zoo1: + image: zookeeper + restart: always + hostname: zoo1 + ports: + - 2281:2181 + environment: + ZOO_MY_ID: 1 + ZOO_SERVERS: server.1=0.0.0.0:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888 + + zoo2: + image: zookeeper + restart: always + hostname: zoo2 + ports: + - 2282:2181 + environment: + ZOO_MY_ID: 2 + ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=0.0.0.0:2888:3888 server.3=zoo3:2888:3888 + + zoo3: + image: zookeeper + restart: always + hostname: zoo3 + ports: + - 2283:2181 + environment: + ZOO_MY_ID: 3 + ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=0.0.0.0:2888:3888 +``` + +- 启动:`docker-compose -f zookeeper.yml -p zk_test up -d` + - 参数 -p zk_test 表示这个 compose project 的名字,等价于:`COMPOSE_PROJECT_NAME=zk_test docker-compose -f zookeeper.yml up -d` + - 不指定项目名称,Docker-Compose 默认以当前文件目录名作为应用的项目名 + - 报错是正常情况的。 +- 停止:`docker-compose -f zookeeper.yml -p zk_test stop` + + +###### MyCAT 单机多个实例 + +- 必须有 JDK 环境(我这里使用的是:1.8.0_171) + +``` +tar -zxvf Mycat-server-1.6.5-release-20180503154132-linux.tar.gz + +mv mycat mycat-1 +``` + +- `cd /usr/local/mycat-1/conf` +- `vim server.xml` + +``` + + + 123456 + + adg_system + + false + + 0 + + 0 + +``` + +- `cd /usr/local/mycat-1/conf` +- `vim schema.xml` + +``` + + + + + + + + + + +
+
+ + +
+ + + +
+
+ + + + + + + + + + + select user() + + + + + select user() + + + + + select user() + + + + + +
+``` + +- `cd /usr/local/mycat-1/conf` +- `vim rule.xml` + +``` + + + shop_id + by-shop-id + + + + + + sharding-by-shop-id.txt + 1 + 0 + +``` + + + +``` +还需要在 conf 新增文件 sharding-by-shop-id.txt 文件,内容是: +需要注意的是: +417454619141211000=0 +417454619141211001=1 +417454619141211002=2 +``` + +``` +CREATE DATABASE adg_system_0000 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +CREATE DATABASE adg_system_0001 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +CREATE DATABASE adg_system_0002 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +``` + + +- 使用 Zookeeper 配置 + +- `vim /usr/local/mycat-1/conf/myid.properties` + +``` +loadZk=true +zkURL=192.168.0.105:2281,192.168.0.105:2282,192.168.0.105:2283 +clusterId=mycat-cluster +myid=mycat_fz_01 +clusterSize=2 +clusterNodes=mycat_fz_01,mycat_fz_02 +#server booster ; booster install on db same server,will reset all minCon to 2 +type=server +boosterDataHosts=dataHost1 +``` + + +- 同步节点配置到 Zookeeper + +``` +cd /usr/local/mycat-1/conf +cp -f schema.xml server.xml rule.xml sharding-by-shop-id.txt zkconf/ + +sh /usr/local/mycat-1/bin/init_zk_data.sh + +``` + +- 重要参数: + +``` +clusterSize=2 表示有几个 MyCAT 节点数量 +``` + +- 解压另外一个节点: + +``` +tar -zxvf Mycat-server-1.6.5-release-20180503154132-linux.tar.gz + +mv mycat mycat-2 + +因为是单机多节点,所以这里需要修改几个端口参数 +vim /usr/local/mycat-2/conf/server.xml + +旧值: +8066 +9066 + +新值: +8067 +9067 + + +vim /usr/local/mycat-2/conf/wrapper.conf + +旧值: +wrapper.java.additional.7=-Dcom.sun.management.jmxremote.port=1984 + +新值: +wrapper.java.additional.7=-Dcom.sun.management.jmxremote.port=1985 +``` + +- 修改另外一个节点配置: + +- `vim /usr/local/mycat-2/conf/myid.properties` + +``` +loadZk=true +zkURL=192.168.0.105:2281,192.168.0.105:2282,192.168.0.105:2283 +clusterId=mycat-cluster +myid=mycat_fz_02 +clusterSize=2 +clusterNodes=mycat_fz_01,mycat_fz_02 +#server booster ; booster install on db same server,will reset all minCon to 2 +type=server +boosterDataHosts=dataHost1 +``` + +- 启动节点: + +``` +cd /usr/local/mycat-1/bin +后台启动:./mycat start && tail -300f /usr/local/mycat-1/logs/mycat.log +控制台启动:./mycat console +控制台启动:cd /usr/local/mycat-1/bin && ./mycat console +重启:./mycat restart +停止:./mycat stop + +cd /usr/local/mycat-2/bin +后台启动:./mycat start && tail -300f /usr/local/mycat-2/logs/mycat.log +控制台启动:./mycat console +控制台启动:cd /usr/local/mycat-2/bin && ./mycat console +重启:./mycat restart +停止:./mycat stop +``` + +- 创建数据结构: + +``` +CREATE TABLE `adg_ads` ( + `ads_id` BIGINT(20) NOT NULL COMMENT '广告表ID', + `ads_set_id` BIGINT(20) NOT NULL COMMENT '广告组表ID', + `ads_title` VARCHAR(32) NOT NULL COMMENT '广告标题', + `shop_id` BIGINT(20) NOT NULL COMMENT '店铺ID', + `channel_id` BIGINT(20) NOT NULL COMMENT '渠道ID', + `shop_name` VARCHAR(32) NOT NULL COMMENT '店铺名称', + `channel_name` VARCHAR(32) NOT NULL COMMENT '渠道名称', + PRIMARY KEY (`ads_id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='广告表'; + + +CREATE TABLE `adg_ads_set` ( + `ads_set_id` BIGINT(20) NOT NULL COMMENT '广告组表ID', + `ads_set_title` VARCHAR(32) NOT NULL COMMENT '广告组标题', + `ads_campaign_id` BIGINT(20) NOT NULL COMMENT '广告系列表ID', + `shop_id` BIGINT(20) NOT NULL COMMENT '店铺ID', + `channel_id` BIGINT(20) NOT NULL COMMENT '渠道ID', + `shop_name` VARCHAR(32) NOT NULL COMMENT '店铺名称', + `channel_name` VARCHAR(32) NOT NULL COMMENT '渠道名称', + PRIMARY KEY (`ads_set_id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='广告组表'; + + +CREATE TABLE `adg_ads_campaign` ( + `ads_campaign_id` BIGINT(20) NOT NULL COMMENT '广告系列表ID', + `ads_campaign_title` VARCHAR(32) NOT NULL COMMENT '广告系列标题', + `shop_id` BIGINT(20) NOT NULL COMMENT '店铺ID', + `channel_id` BIGINT(20) NOT NULL COMMENT '渠道ID', + `shop_name` VARCHAR(32) NOT NULL COMMENT '店铺名称', + `channel_name` VARCHAR(32) NOT NULL COMMENT '渠道名称', + PRIMARY KEY (`ads_campaign_id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='广告系列表'; + + +CREATE TABLE `adg_channel` ( + `channel_id` BIGINT(20) NOT NULL COMMENT '渠道ID', + `channel_name` VARCHAR(32) NOT NULL COMMENT '渠道名称', + PRIMARY KEY (`channel_id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='渠道表'; + + +CREATE TABLE `adg_shop` ( + `shop_id` BIGINT(20) NOT NULL COMMENT '店铺ID', + `shop_name` VARCHAR(32) NOT NULL COMMENT '店铺名称', + PRIMARY KEY (`shop_id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='商品表'; + + +CREATE TABLE `adg_shop_channel` ( + `shop_channel_id` BIGINT(20) NOT NULL COMMENT '店铺渠道中间表ID', + `shop_id` BIGINT(20) NOT NULL COMMENT '店铺ID', + `channel_id` BIGINT(20) NOT NULL COMMENT '渠道ID', + `shop_name` VARCHAR(32) NOT NULL COMMENT '店铺名称', + `channel_name` VARCHAR(32) NOT NULL COMMENT '渠道名称', + PRIMARY KEY (`shop_channel_id`) +) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='店铺渠道中间表'; +``` + + + +``` +INSERT INTO `adg_shop`(`shop_id`,`shop_name`) VALUES (417454619141211000,'NC站'); +INSERT INTO `adg_shop`(`shop_id`,`shop_name`) VALUES (417454619141211001,'BG站'); + +INSERT INTO `adg_channel`(`channel_id`,`channel_name`) VALUES (1,'Facebook'); +INSERT INTO `adg_channel`(`channel_id`,`channel_name`) VALUES (2,'Google'); +INSERT INTO `adg_channel`(`channel_id`,`channel_name`) VALUES (3,'Twitter'); + +INSERT INTO `adg_shop_channel`(`shop_channel_id`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (1,417454619141211000,1,'NC站','Facebook'); +INSERT INTO `adg_shop_channel`(`shop_channel_id`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (2,417454619141211000,2,'NC站','Google'); +INSERT INTO `adg_shop_channel`(`shop_channel_id`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (3,417454619141211001,1,'BG站','Facebook'); +INSERT INTO `adg_shop_channel`(`shop_channel_id`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (4,417454619141211001,2,'BG站','Google'); + +INSERT INTO `adg_ads_campaign`(`ads_campaign_id`,`ads_campaign_title`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (1,'第1个广告系列',417454619141211000,1,'NC站','Facebook'); +INSERT INTO `adg_ads_campaign`(`ads_campaign_id`,`ads_campaign_title`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (2,'第2个广告系列',417454619141211001,2,'BG站','Google'); + +INSERT INTO `adg_ads_set`(`ads_set_id`,`ads_set_title`,`ads_campaign_id`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (1,'第1个广告集',1,417454619141211000,1,'NC站','Facebook'); +INSERT INTO `adg_ads_set`(`ads_set_id`,`ads_set_title`,`ads_campaign_id`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (2,'第2个广告集',2,417454619141211001,2,'BG站','Google'); + +INSERT INTO `adg_ads`(`ads_id`,`ads_set_id`,`ads_title`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (1,1,'第1个广告',417454619141211000,1,'NC站','Facebook'); +INSERT INTO `adg_ads`(`ads_id`,`ads_set_id`,`ads_title`,`shop_id`,`channel_id`,`shop_name`,`channel_name`) VALUES (2,2,'第2个广告',417454619141211001,2,'BG站','Google'); +``` + + +#### HAProxy + Keepalived + +``` + +``` + +------------------------------------------------------------------------------ + + +## 资料 + +- 书:《分布式数据库架构及企业实践-基于 Mycat 中间件》 diff --git a/markdown-file/Mysql-Install-And-Settings.md b/markdown-file/Mysql-Install-And-Settings.md new file mode 100644 index 00000000..5eb73d43 --- /dev/null +++ b/markdown-file/Mysql-Install-And-Settings.md @@ -0,0 +1,401 @@ +# MySQL 安装和配置 + + +## Docker 安装 MySQL(不带挂载) + +``` +docker run \ + --name mysql-jira \ + --restart always \ + -p 3306:3306 \ + -e MYSQL_ROOT_PASSWORD=adg_123456 \ + -e MYSQL_DATABASE=jira_db \ + -e MYSQL_USER=jira_user \ + -e MYSQL_PASSWORD=jira_123456 \ + -d \ + mysql:5.7 +``` + + +- 连上容器:`docker exec -it mysql-jira /bin/bash` + - 连上 MySQL:`mysql -u root -p` +- 设置编码: + +``` +SET NAMES 'utf8mb4'; +alter database jira_db character set utf8mb4; +``` + + + +## Docker 安装 MySQL(带挂载) + +- 关掉:SELinux +- 创建本地数据存储 + 配置文件目录:`mkdir -p /data/docker/mysql/datadir /data/docker/mysql/conf /data/docker/mysql/log` +- 在宿主机上创建一个配置文件:`vim /data/docker/mysql/conf/mysql-1.cnf`,内容如下: + +``` +# 该编码设置是我自己配置的 +[mysql] +default-character-set = utf8mb4 + +# 下面内容是 docker mysql 默认的 start +[mysqld] +pid-file = /var/run/mysqld/mysqld.pid +socket = /var/run/mysqld/mysqld.sock +datadir = /var/lib/mysql +#log-error = /var/log/mysql/error.log +# By default we only accept connections from localhost +#bind-address = 127.0.0.1 +# Disabling symbolic-links is recommended to prevent assorted security risks +symbolic-links=0 +# 上面内容是 docker mysql 默认的 end + +# 下面开始的内容就是我自己配置的 +log-error=/var/log/mysql/error.log +default-storage-engine = InnoDB +collation-server = utf8mb4_unicode_ci +init_connect = 'SET NAMES utf8mb4' +character-set-server = utf8mb4 +lower_case_table_names = 1 +max_allowed_packet = 50M +``` + +- 赋权(避免挂载的时候,一些程序需要容器中的用户的特定权限使用):`chmod -R 777 /data/docker/mysql/datadir /data/docker/mysql/log` +- 赋权:`chown -R 0:0 /data/docker/mysql/conf` + - 配置文件的赋权比较特殊,如果是给 777 权限会报:[Warning] World-writable config file '/etc/mysql/conf.d/mysql-1.cnf' is ignored,所以这里要特殊对待。容器内是用 root 的 uid,所以这里与之相匹配赋权即可。 + - 我是进入容器 bash 内,输入:`whoami && id`,看到默认用户的 uid 是 0,所以这里才 chown 0 +- `docker run -p 3306:3306 --name cloud-mysql -v /data/docker/mysql/datadir:/var/lib/mysql -v /data/docker/mysql/log:/var/log/mysql -v /data/docker/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7` +- 连上容器:`docker exec -it cloud-mysql /bin/bash` + - 连上 MySQL:`mysql -u root -p` + - 创建表:`CREATE DATABASE wormhole DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;` +- 关于容器的 MySQL 配置,官网是这样说的: + +>> The MySQL startup configuration is specified in the file /etc/mysql/my.cnf, and that file in turn includes any files found in the /etc/mysql/conf.d directory that end with .cnf.Settings in files in this directory will augment and/or override settings in /etc/mysql/my.cnf. If you want to use a customized MySQL configuration,you can create your alternative configuration file in a directory on the host machine and then mount that directory location as /etc/mysql/conf.d inside the mysql container. + +- 容器中的 my.cnf 内容如下: + +``` +# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +!includedir /etc/mysql/conf.d/ +!includedir /etc/mysql/mysql.conf.d/ +``` + +- docker 的 MySQL 备份和还原: + - 备份:`docker exec cloud-mysql /usr/bin/mysqldump -u root --password=123456 DATABASE_Name > /opt/backup.sql` + - 还原:`docker exec -i cloud-mysql /usr/bin/mysql -u root --password=123456 DATABASE_Name < /opt/backup.sql` + +------------------------------------------------------------------- + + +## MySQL 5.5 安装 + +- [来源](https://blog.csdn.net/qingtian_1993/article/details/79692479) +- 设置仓库 + +``` +rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm +rpm -Uvh https://mirror.webtatic.com/yum/el6/latest.rpm +``` + +- 安装:`yum install mysql55w mysql55w-server`,用同时生产 mysql 的组和用户 +- 启动:`service mysqld start` +- 重置密码:`mysqladmin -u root password '123456'` +- 默认配置文件:`vim /etc/my.cnf` +- log 目录:`cd /var/log/mysqld.log` +- 查看服务 log:`tail -300 /var/log/mysqld.log` +- 给指定目录增加 mysql 用户组权限:`chown mysql.mysql /var/run/mysqld/` +- 官网 MySQL 启动失败,这篇文章经验值得推荐:[CentOS 7下MySQL服务启动失败的解决思路](https://www.cnblogs.com/ivictor/p/5146247.html) + +------------------------------------------------------------------- + +## MySQL 5.6 安装 + +- 假设当前用户为:root +- Mysql 安装 + - 官网: + - 官网下载: + - 官网 5.5 下载: + - 官网 5.6 下载: + - 官网 5.7 下载: + - 官网帮助中心: + - 此时(20160210) Mysql 5.5 最新版本为:**5.5.48** + - 此时(20170130) Mysql 5.6 最新版本为:**5.6.35** + - 此时(20160210) Mysql 5.7 最新版本为:**5.7.11** + - 我个人习惯 `/opt` 目录下创建一个目录 `setups` 用来存放各种软件安装包;在 `/usr` 目录下创建一个 `program` 用来存放各种解压后的软件包,下面的讲解也都是基于此习惯 + - 我个人已经使用了第三方源:`EPEL、RepoForge`,如果你出现 `yum install XXXXX` 安装不成功的话,很有可能就是你没有相关源,请查看我对源设置的文章 + - Mysql 5.6 下载:`wget http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.35.tar.gz` (大小:31 M) + - Mysql 5.7 下载:`wget http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.11.tar.gz` (大小:47 M) + - 我们这次安装以 5.6 为实例 + - 进入下载目录:`cd /opt/setups` + - 解压压缩包:`tar zxvf mysql-5.6.35.tar.gz` + - 移到解压包:`mv /opt/setups/mysql-5.6.35 /usr/local/` + - 安装依赖包、编译包:`yum install -y make gcc-c++ cmake bison-devel ncurses-devel autoconf` + - 进入解压目录:`cd /usr/local/mysql-5.6.35/` + - 生成安装目录:`mkdir -p /usr/local/mysql/data` + - 生成配置(使用 InnoDB):`cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data -DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DDEFAULT_CHARSET=utf8mb4 -DDEFAULT_COLLATION=utf8mb4_unicode_ci -DWITH_EXTRA_CHARSETS:STRING=utf8mb4 -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DENABLED_LOCAL_INFILE=1` + - 更多参数说明可以查看: + - 编译:`make`,这个过程比较漫长,一般都在 30 分钟左右,具体还得看机子配置,如果最后结果有 error,建议删除整个 mysql 目录后重新解压一个出来继续处理 + - 安装:`make install` + - 配置开机启动: + - `cp /usr/local/mysql-5.6.35/support-files/mysql.server /etc/init.d/mysql` + - `chmod 755 /etc/init.d/mysql` + - `chkconfig mysql on` + - 复制一份配置文件: `cp /usr/local/mysql-5.6.35/support-files/my-default.cnf /etc/my.cnf` + - 删除安装的目录:`rm -rf /usr/local/mysql-5.6.35/` + - 添加组和用户及安装目录权限 + - `groupadd mysql` #添加组 + - `useradd -g mysql mysql -s /bin/false` #创建用户mysql并加入到mysql组,不允许mysql用户直接登录系统 + - `chown -R mysql:mysql /usr/local/mysql/data` #设置MySQL数据库目录权限 + - 初始化数据库:`/usr/local/mysql/scripts/mysql_install_db --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --skip-name-resolve --user=mysql` + - 开放防火墙端口: + - `iptables -I INPUT -p tcp -m tcp --dport 3306 -j ACCEPT` + - `service iptables save` + - `service iptables restart` + - 禁用 selinux + - 编辑配置文件:`vim /etc/selinux/config` + - 把 `SELINUX=enforcing` 改为 `SELINUX=disabled` + - 常用命令软连接,才可以在终端直接使用:mysql 和 mysqladmin 命令 + - `ln -s /usr/local/mysql/bin/mysql /usr/bin` + - `ln -s /usr/local/mysql/bin/mysqladmin /usr/bin` + - `ln -s /usr/local/mysql/bin/mysqldump /usr/bin` + - `ln -s /usr/local/mysql/bin/mysqlslap /usr/bin` + +## MySQL 5.7 YUM 安装 + +- 官网: + +``` + +禁用 selinux:setenforce 0 + +wget https://repo.mysql.com//mysql57-community-release-el7-11.noarch.rpm +yum localinstall mysql57-community-release-el7-11.noarch.rpm +yum install mysql-community-server +一共 194M + +配置文件:/etc/my.cnf +systemctl start mysqld +systemctl status mysqld + +查看初次使用的临时密码:grep 'temporary password' /var/log/mysqld.log + +``` + +------------------------------------------------------------------- + + +## MySQL 配置 + +- 官网配置参数解释: +- 找一下当前系统中有多少个 my.cnf 文件:`find / -name "my.cnf"`,我查到的结果: + +``` nginx +/etc/my.cnf +/usr/local/mysql/my.cnf +/usr/local/mysql/mysql-test/suite/ndb/my.cnf +/usr/local/mysql/mysql-test/suite/ndb_big/my.cnf +............. +/usr/local/mysql/mysql-test/suite/ndb_rpl/my.cnf +``` + + +- 保留 **/etc/my.cnf** 和 **/usr/local/mysql/mysql-test/** 目录下配置文件,其他删除掉。 +- 我整理的一个单机版配置说明(MySQL 5.6,适用于 1G 内存的服务器): + - [my.cnf](MySQL-Settings/MySQL-5.6/1G-Memory-Machine/my-for-comprehensive.cnf) +- 其中我测试的结果,在不适用任何配置修改的情况下,1G 内存安装 MySQL 5.6 默认就会占用 400M 左右的内存,要降下来的核心配置要补上这几个参数: + +``` +performance_schema_max_table_instances=400 +table_definition_cache=400 +table_open_cache=256 +``` + +## 修改 root 账号密码 + +- 启动 Mysql 服务器(CentOS 6):`service mysql start` +- 启动 Mysql 服务器(CentOS 7):`systemctl start mysql` +- 查看是否已经启动了:`ps aux | grep mysql` +- 默认安装情况下,root 的密码是空,所以为了方便我们可以设置一个密码,假设我设置为:123456 +- 终端下执行:`mysql -uroot` + - 现在进入了 mysql 命令行管理界面,输入:`SET PASSWORD = PASSWORD('123456');FLUSH PRIVILEGES;` + - 现在进入了 mysql 命令行管理界面,输入:`UPDATE user SET authentication_string=PASSWORD('123456') where USER='root';FLUSH PRIVILEGES;` +- 修改密码后,终端下执行:`mysql -uroot -p` + - 根据提示,输入密码进度 mysql 命令行状态。 +- 如果你在其他机子上连接该数据库机子报:**Access denied for user 'root'@'localhost' (using password: YES)** + - 解决办法: + - 在终端中执行(CentOS 6):`service mysql stop` + - 在终端中执行(CentOS 7):`systemctl stop mysql` + - 在终端中执行(前面添加的 Linux 用户 mysql 必须有存在):`/usr/local/mysql/bin/mysqld --skip-grant-tables --user=mysql` + - 此时 MySQL 服务会一直处于监听状态,你需要另起一个终端窗口来执行接下来的操作 + - 在终端中执行:`mysql -u root mysql` 或者:`mysql -h 127.0.0.1 -u root -P 3306 -p` + - 把密码改为:123456,进入 MySQL 命令后执行:`UPDATE user SET Password=PASSWORD('123456') where USER='root';FLUSH PRIVILEGES;` + - 然后重启 MySQL 服务(CentOS 6):`service mysql restart` + - 然后重启 MySQL 服务(CentOS 7):`systemctl restart mysql` + +## 连接报错:"Host '192.168.1.133' is not allowed to connect to this MySQL server" + +- 不允许除了 localhost 之外去连接,解决办法,进入 MySQL 命令行,输入下面内容: +- 开发机设置允许任何机子访问: + - `vim /etc/my.cnf` 中不能有:`bind-address = 127.0.0.1` + - 配置:`GRANT ALL PRIVILEGES ON *.* TO '数据库用户名'@'%' IDENTIFIED BY '数据库用户名的密码' WITH GRANT OPTION;` + - 更新配置:`flush privileges;` +- 生产机设置只运行本机访问: + - `vim /etc/my.cnf` 中必须有:`bind-address = 127.0.0.1` + - 配置:`GRANT ALL PRIVILEGES ON *.* TO '数据库用户名'@'127.0.0.1' IDENTIFIED BY '数据库用户名的密码' WITH GRANT OPTION;` + - 更新配置:`flush privileges;` + + +## 修改密码报错:Your password does not satisfy the current policy requirements + +- MySQL 5.7 安全性要求更高,需要这么做: + +``` +set global validate_password_policy=0; #密码强度设为最低等级 +set global validate_password_length=6; #密码允许最小长度为6 +set password = password('新密码'); +FLUSH PRIVILEGES; +``` + +## MySQL 5.7 + +- 报错内容: + +``` +Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column 'youmeek.nm.id' +which is not functionally dependent on columns in GROUP BY clause; +this is incompatible with sql_mode=only_full_group_by +``` + +- 查下自己的模式:`select version(), @@sql_mode;` +- 解决办法,修改 my.cnf,增加这一行: + +``` +sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION; +``` + + +## 小内存机子,MySQL 频繁挂掉解决办法(1G + CentOS 7.4) + +- 保存系统日志到本地进行查看:`cd /var/log/ && sz messages` +- 其中可以看到这样的几句话(可以知道内存不够了): + +``` +Jul 6 21:49:14 VM_123_201_centos kernel: Out of memory: Kill process 19452 (httpd) score 36 or sacrifice child +Jul 6 21:49:14 VM_123_201_centos kernel: Killed process 19452 (httpd) total-vm:516404kB, anon-rss:36088kB, file-rss:168kB, shmem-rss:12kB +``` + +- 对于 1G 的内存 MySQL(5.6.35),建议重点下面配置: + +``` +[mysqld] +table_definition_cache=400 +table_open_cache=256 +innodb_buffer_pool_size = 64M +max_connections = 100 +``` + +- 增加 swap(云服务基本都是没 swap 的) +- 分别执行下面 shell 命令: + +``` +dd if=/dev/zero of=/swapfile bs=1M count=1024 +mkswap /swapfile +swapon /swapfile +``` + +- 修改配置文件:`vim /etc/fstab` + - 添加这句在文件最后一行:`/swapfile swap swap defauluts 0 0` +- 重启机子:`reboot` + +## MySQL 主从复制 + +### 环境说明和注意点 + +- 假设有两台服务器,一台做主,一台做从 + - MySQL 主信息: + - IP:**12.168.1.113** + - 端口:**3306** + - MySQL 从信息: + - IP:**12.168.1.115** + - 端口:**3306** +- 注意点 + - 主 DB server 和从 DB server 数据库的版本一致 + - 主 DB server 和从 DB server 数据库数据一致 + - 主 DB server 开启二进制日志,主 DB server 和从 DB server 的 server-id 都必须唯一 +- 优先操作: + - **把主库的数据库复制到从库并导入** + +### 主库机子操作 + +- 主库操作步骤 + - 创建一个目录:`mkdir -p /usr/local/mysql/data/mysql-bin` + - 主 DB 开启二进制日志功能:`vim /etc/my.cnf`, + - 添加一行:`log-bin = /usr/local/mysql/data/mysql-bin` + - 指定同步的数据库,如果不指定则同步全部数据库,其中 ssm 是我的数据库名:`binlog-do-db=ssm` + - 主库关掉慢查询记录,用 SQL 语句查看当前是否开启:`SHOW VARIABLES LIKE '%slow_query_log%';`,如果显示 OFF 则表示关闭,ON 表示开启 + - 重启主库 MySQL 服务 + - 进入 MySQL 命令行状态,执行 SQL 语句查询状态:`SHOW MASTER STATUS;` + - 在显示的结果中,我们需要记录下 **File** 和 **Position** 值,等下从库配置有用。 + - 设置授权用户 slave01 使用 123456 密码登录主库,这里 @ 后的 IP 为从库机子的 IP 地址,如果从库的机子有多个,我们需要多个这个 SQL 语句。 + + ``` SQL + grant replication slave on *.* to 'slave01'@'192.168.1.135' identified by '123456'; + flush privileges; + ``` + + +### 从库机子操作 + + +- 从库操作步骤 + - 从库开启慢查询记录,用 SQL 语句查看当前是否开启:`SHOW VARIABLES LIKE '%slow_query_log%';`,如果显示 OFF 则表示关闭,ON 表示开启。 + - 测试从库机子是否能连上主库机子:`mysql -h 192.168.1.105 -u slave01 -p`,必须要连上下面的操作才有意义。 + - 由于不能排除是不是系统防火墙的问题,所以建议连不上临时关掉防火墙:`service iptables stop` + - 或是添加防火墙规则: + - 添加规则:`iptables -I INPUT -p tcp -m tcp --dport 3306 -j ACCEPT` + - 保存规则:`service iptables save` + - 重启 iptables:`service iptables restart` + - 修改配置文件:`vim /etc/my.cnf`,把 server-id 改为跟主库不一样 + - 在进入 MySQL 的命令行状态下,输入下面 SQL: + + ``` SQL + CHANGE MASTER TO + master_host='192.168.1.113', + master_user='slave01', + master_password='123456', + master_port=3306, + master_log_file='mysql3306-bin.000006',>>>这个值复制刚刚让你记录的值 + master_log_pos=1120;>>>这个值复制刚刚让你记录的值 + ``` + +- 执行该 SQL 语句,启动 slave 同步:`START SLAVE;` +- 执行该 SQL 语句,查看从库机子同步状态:`SHOW SLAVE STATUS;` +- 在查看结果中必须下面两个值都是 Yes 才表示配置成功: + - `Slave_IO_Running:Yes` + - 如果不是 Yes 也不是 No,而是 Connecting,那就表示从机连不上主库,需要你进一步排查连接问题。 + - `Slave_SQL_Running:Yes` +- 如果你的 Slave_IO_Running 是 No,一般如果你是在虚拟机上测试的话,从库的虚拟机是从主库的虚拟机上复制过来的,那一般都会这样的,因为两台的 MySQL 的 UUID 值一样。你可以检查从库下的错误日志:`cat /usr/local/mysql/data/mysql-error.log` + - 如果里面提示 uuid 错误,你可以编辑从库的这个配置文件:`vim /usr/local/mysql/data/auto.cnf`,把配置文件中的:server-uuid 值随便改一下,保证和主库是不一样即可。 + + + + + +## 资料 + +- diff --git a/markdown-file/Mysql-Optimize.md b/markdown-file/Mysql-Optimize.md new file mode 100644 index 00000000..cd0c58d5 --- /dev/null +++ b/markdown-file/Mysql-Optimize.md @@ -0,0 +1,300 @@ +# MySQL 优化 + + +- 下面说的优化基于 MySQL 5.6,理论上 5.5 之后的都算适用,具体还是要看官网 + +## 优秀材料 + +- +- +- <> +- <> +- <> + + +## 服务状态查询 + +- 查看当前数据库的状态,常用的有: + - 查看系统状态:`SHOW STATUS;` + - 查看刚刚执行 SQL 是否有警告信息:`SHOW WARNINGS;` + - 查看刚刚执行 SQL 是否有错误信息:`SHOW ERRORS;` + - 查看已经连接的所有线程状况:`SHOW FULL PROCESSLIST;` + - 输出参数说明: + - 可以结束某些连接:`kill id值` + - 查看当前连接数量:`SHOW STATUS LIKE 'max_used_connections';` + - 查看变量,在 my.cnf 中配置的变量会在这里显示:`SHOW VARIABLES;` + - 查询慢 SQL 配置:`show variables like 'slow%';` + - 开启慢 SQL:`set global slow_query_log='ON'` + - 查询慢 SQL 秒数值:` show variables like 'long%';` + - 调整秒速值:`set long_query_time=1;` + - 查看当前MySQL 中已经记录了多少条慢查询,前提是配置文件中开启慢查询记录了. + - `SHOW STATUS LIKE '%slow_queries%';` + - 查询当前MySQL中查询、更新、删除执行多少条了,可以通过这个来判断系统是侧重于读还是侧重于写,如果是写要考虑使用读写分离。 + - `SHOW STATUS LIKE '%Com_select%';` + - `SHOW STATUS LIKE '%Com_insert%';` + - `SHOW STATUS LIKE '%Com_update%';` + - `SHOW STATUS LIKE '%Com_delete%';` + - 如果 rollback 过多,说明程序肯定哪里存在问题 + - `SHOW STATUS LIKE '%Com_rollback%';` + - 显示MySQL服务启动运行了多少时间,如果MySQL服务重启,该时间重新计算,单位秒 + - `SHOW STATUS LIKE 'uptime';` + - 显示查询缓存的状态情况 + - `SHOW STATUS LIKE 'qcache%';` + - PS.下面的解释,我目前不肯定是对,还要再找下资料: + - + - + - + - + - 1. Qcache_free_blocks,缓存中相邻内存块的个数。数目大说明可能有碎片。如果数目比较大,可以执行: `flush query cache;` 对缓存中的碎片进行整理,从而得到一个空闲块。 + - 2. Qcache_free_memory,缓存中的空闲内存大小。如果 Qcache_free_blocks 比较大,说明碎片严重。 如果 Qcache_free_memory 很小,说明缓存不够用了。 + - 3. Qcache_hits,每次查询在缓存中命中时就增大该值。 + - 4. Qcache_inserts,每次查询,如果没有从缓存中找到数据,这里会增大该值 + - 5. Qcache_lowmem_prunes,因内存不足删除缓存次数,缓存出现内存不足并且必须要进行清理, 以便为更多查询提供空间的次数。返个数字最好长时间来看;如果返个数字在不断增长,就表示可能碎片非常严重,或者缓存内存很少。 + - 6. Qcache_not_cached # 没有进行缓存的查询的数量,通常是这些查询未被缓存或其类型不允许被缓存 + - 7. Qcache_queries_in_cache # 在当前缓存的查询(和响应)的数量。 + - 8. Qcache_total_blocks #缓存中块的数量。 +- 查询哪些表在被使用,是否有锁表:`SHOW OPEN TABLES WHERE In_use > 0;` +- 查询 innodb 状态(输出内容很多):`SHOW ENGINE INNODB STATUS;` +- 锁性能状态:`SHOW STATUS LIKE 'innodb_row_lock_%';` + - Innodb_row_lock_current_waits:当前等待锁的数量 + - Innodb_row_lock_time:系统启动到现在、锁定的总时间长度 + - Innodb_row_lock_time_avg:每次平均锁定的时间 + - Innodb_row_lock_time_max:最长一次锁定时间 + - Innodb_row_lock_waits:系统启动到现在、总共锁定次数 +- 帮我们分析表,并提出建议:`select * from my_table procedure analyse();` + + +## 系统表 + +- 当前运行的所有事务:`select * from information_schema.INNODB_TRX;` +- 当前事务出现的锁:`select * from information_schema.INNODB_LOCKS;` +- 锁等待的对应关系:`select * from information_schema.INNODB_LOCK_WAITS;` + + +## otpimizer trace + +- 作用:输入我们想要查看优化过程的查询语句,当该查询语句执行完成后,就可以到 information_schema 数据库下的OPTIMIZER_TRACE表中查看 mysql 自己帮我们的完整优化过程 +- 是否打开(默认都是关闭):`SHOW VARIABLES LIKE 'optimizer_trace';` + - one_line的值是控制输出格式的,如果为on那么所有输出都将在一行中展示,不适合人阅读,所以我们就保持其默认值为off吧。 +- 打开配置:`SET optimizer_trace="enabled=on";` +- 关闭配置:`SET optimizer_trace="enabled=off";` +- 查询优化结果:`SELECT * FROM information_schema.OPTIMIZER_TRACE;` + +``` +我们所说的基于成本的优化主要集中在optimize阶段,对于单表查询来说,我们主要关注optimize阶段的"rows_estimation"这个过程,这个过程深入分析了对单表查询的各种执行方案的成本; +对于多表连接查询来说,我们更多需要关注"considered_execution_plans"这个过程,这个过程里会写明各种不同的连接方式所对应的成本。 +反正优化器最终会选择成本最低的那种方案来作为最终的执行计划,也就是我们使用EXPLAIN语句所展现出的那种方案。 +如果有小伙伴对使用EXPLAIN语句展示出的对某个查询的执行计划很不理解,大家可以尝试使用optimizer trace功能来详细了解每一种执行方案对应的成本,相信这个功能能让大家更深入的了解MySQL查询优化器。 +``` + + + +## 查询优化(EXPLAIN 查看执行计划) + +- 使用 EXPLAIN 进行 SQL 语句分析:`EXPLAIN SELECT * FROM sys_user;`,效果如下: + +``` +id|select_type|table |partitions|type|possible_keys|key|key_len|ref|rows|filtered|Extra| +--|-----------|--------|----------|----|-------------|---|-------|---|----|--------|-----| + 1|SIMPLE |sys_user| |ALL | | | | | 2| 100| | +``` + +- 简单描述 + - `id`:在一个大的查询语句中每个 SELECT 关键字都对应一个唯一的id + - `select_type`:SELECT 关键字对应的那个查询的类型 + - `table`:表名 + - `partitions`:匹配的分区信息 + - `type`:针对单表的访问方法 + - `possible_keys`:可能用到的索引 + - `key`:实际上使用的索引 + - `key_len`:实际使用到的索引长度 + - `ref`:当使用索引列等值查询时,与索引列进行等值匹配的对象信息 + - `rows`:预估的需要读取的记录条数 + - `filtered`:某个表经过搜索条件过滤后剩余记录条数的百分比 + - `Extra`:一些额外的信息 +- 有多个结果的场景分析 + - 有子查询的一般都会有多个结果,id 是递增值。但是,有些场景查询优化器可能对子查询进行重写,转换为连接查询。所以有时候 id 就不是自增值。 + - 对于连接查询一般也会有多个接口,id 可能是相同值,相同值情况下,排在前面的记录表示驱动表,后面的表示被驱动表 + - UNION 场景会有 id 为 NULL 的情况,这是一个去重后临时表,合并多个结果集的临时表。但是,UNION ALL 不会有这种情况,因为这个不需要去重。 +- 根据具体的描述: + - **id**,该列表示当前结果序号 + - **select_type**,表示 SELECT 语句的类型,有下面几种 + - `SIMPLE`:表示简单查询,其中不包括 UNION 查询和子查询 + - `PRIMARY`:对于包含UNION、UNION ALL或者子查询的大查询来说,它是由几个小查询组成的,其中最左边的那个查询的select_type值就是PRIMARY + - `UNION`:对于包含UNION或者UNION ALL的大查询来说,它是由几个小查询组成的,其中除了最左边的那个小查询以外,其余的小查询的select_type值就是UNION + - `UNION RESULT`:MySQL选择使用临时表来完成UNION查询的去重工作,针对该临时表的查询的select_type就是UNION RESULT + - `SUBQUERY`:如果包含子查询的查询语句不能够转为对应的semi-join的形式,并且该子查询是不相关子查询,并且查询优化器决定采用将该子查询物化的方案来执行该子查询时,该子查询的第一个SELECT关键字代表的那个查询的select_type就是SUBQUERY + - `DEPENDENT SUBQUERY`:如果包含子查询的查询语句不能够转为对应的semi-join的形式,并且该子查询是相关子查询,则该子查询的第一个SELECT关键字代表的那个查询的select_type就是DEPENDENT SUBQUERY + - `DEPENDENT UNION`:在包含UNION或者UNION ALL的大查询中,如果各个小查询都依赖于外层查询的话,那除了最左边的那个小查询之外,其余的小查询的select_type的值就是DEPENDENT UNION + - `DERIVED`:对于采用物化的方式执行的包含派生表的查询,该派生表对应的子查询的select_type就是DERIVED + - `MATERIALIZED`:当查询优化器在执行包含子查询的语句时,选择将子查询物化之后与外层查询进行连接查询时,该子查询对应的select_type属性就是MATERIALIZED + - 还有其他一些 + - **table**,表名或者是子查询的一个结果集 + - **type**,表示表的链接类型,分别有(以下的连接类型的顺序是从最佳类型到最差类型)**(这个属性重要)**: + - 性能好: + - `system`:当表中只有一条记录并且该表使用的存储引擎的统计数据是精确的,比如MyISAM、Memory,那么对该表的访问方法就是system,平时不会出现,这个也可以忽略不计。 + - `const`:当我们根据主键或者唯一二级索引列与常数进行等值匹配时,对单表的访问方法就是const,常用于 PRIMARY KEY 或者 UNIQUE 索引的查询,可理解为 const 是最优化的。 + - `eq_ref`:在连接查询时,如果被驱动表是通过主键或者唯一二级索引列等值匹配的方式进行访问的(如果该主键或者唯一二级索引是联合索引的话,所有的索引列都必须进行等值比较),则对该被驱动表的访问方法就是eq_ref + - `ref`:当通过普通的二级索引列与常量进行等值匹配时来查询某个表,那么对该表的访问方法就可能是ref。ref 可用于 = 或 < 或 > 操作符的带索引的列。 + - `ref_or_null`:当对普通二级索引进行等值匹配查询,该索引列的值也可以是NULL值时,那么对该表的访问方法就可能是ref_or_null + - 性能较差: + - `index_merge`:该联接类型表示使用了索引合并优化方法。在这种情况下,key 列包含了使用的索引的清单,key_len 包含了使用的索引的最长的关键元素。 + - `unique_subquery`:类似于两表连接中被驱动表的eq_ref访问方法,unique_subquery是针对在一些包含IN子查询的查询语句中,如果查询优化器决定将IN子查询转换为EXISTS子查询,而且子查询可以使用到主键进行等值匹配的话,那么该子查询执行计划的type列的值就是unique_subquery + - `index_subquery`:index_subquery与unique_subquery类似,只不过访问子查询中的表时使用的是普通的索引 + - `range`:只检索给定范围的行, 使用一个索引来选择行。 + - `index`:该联接类型与 ALL 相同, 除了只有索引树被扫描。这通常比 ALL 快, 因为索引文件通常比数据文件小。 + - 再一次强调,对于使用InnoDB存储引擎的表来说,二级索引的记录只包含索引列和主键列的值,而聚簇索引中包含用户定义的全部列以及一些隐藏列,所以扫描二级索引的代价比直接全表扫描,也就是扫描聚簇索引的代价更低一些 + - 性能最差: + - `ALL`:对于每个来自于先前的表的行组合, 进行完整的表扫描。(性能最差) + - `possible_keys`,指出 MySQL 能使用哪个索引在该表中找到行。如果该列为 NULL,说明没有使用索引,可以对该列创建索引来提供性能。**(这个属性重要)** + - possible_keys列中的值并不是越多越好,可能使用的索引越多,查询优化器计算查询成本时就得花费更长时间,所以如果可以的话,尽量删除那些用不到的索引。 + - `key`,显示 MySQL 实际决定使用的键 (索引)。如果没有选择索引, 键是 NULL。**(这个属性重要)** + - 不过有一点比较特别,就是在使用index访问方法来查询某个表时,possible_keys列是空的,而key列展示的是实际使用到的索引 + - `key_len`,表示当优化器决定使用某个索引执行查询时,该索引记录的最大长度。如果键是可以为 NULL, 则长度多 1。 + - `ref`,显示使用哪个列或常数与 key 一起从表中选择行。 + - `rows`,显示 MySQL 认为它执行查询时必须检查的行数。**(这个属性重要)** + - `Extra`,该列包含 MySQL 解决查询的详细信息: + - `Distinct` MySQL 发现第 1 个匹配行后, 停止为当前的行组合搜索更多的行。 + - `Not exists` 当我们使用左(外)连接时,如果WHERE子句中包含要求被驱动表的某个列等于NULL值的搜索条件,而且那个列又是不允许存储NULL值的,那么在该表的执行计划的Extra列就会提示Not exists额外信息 + - `range checked for each record (index map: #)` MySQL 没有发现好的可以使用的索引, 但发现如果来自前面的表的列值已知, 可能部分索引可以使用。 + - `Using filesort` 有一些情况下对结果集中的记录进行排序是可以使用到索引的 + - 需要注意的是,如果查询中需要使用filesort的方式进行排序的记录非常多,那么这个过程是很耗费性能的,我们最好想办法将使用文件排序的执行方式改为使用索引进行排序。 + - `Using temporary` 在许多查询的执行过程中,MySQL可能会借助临时表来完成一些功能,比如去重、排序之类的,比如我们在执行许多包含DISTINCT、GROUP BY、UNION等子句的查询过程中,如果不能有效利用索引来完成查询,MySQL很有可能寻求通过建立内部的临时表来执行查询。如果查询中使用到了内部的临时表,在执行计划的Extra列将会显示Using temporary提示 + - 如果我们并不想为包含GROUP BY子句的查询进行排序,需要我们显式的写上:ORDER BY NULL + - 执行计划中出现Using temporary并不是一个好的征兆,因为建立与维护临时表要付出很大成本的,所以我们最好能使用索引来替代掉使用临时表 + - `Using join buffer (Block Nested Loop)` 在连接查询执行过程过,当被驱动表不能有效的利用索引加快访问速度,MySQL一般会为其分配一块名叫join buffer的内存块来加快查询速度,也就是我们所讲的基于块的嵌套循环算法 + - `Using where` + - 当我们使用全表扫描来执行对某个表的查询,并且该语句的WHERE子句中有针对该表的搜索条件时,在Extra列中会提示上述额外信息 + - 当使用索引访问来执行对某个表的查询,并且该语句的WHERE子句中有除了该索引包含的列之外的其他搜索条件时,在Extra列中也会提示上述额外信息 + - `Using sort_union(...), Using union(...), Using intersect(...)` 如果执行计划的Extra列出现了Using intersect(...)提示,说明准备使用Intersect索引合并的方式执行查询,括号中的...表示需要进行索引合并的索引名称;如果出现了Using union(...)提示,说明准备使用Union索引合并的方式执行查询;出现了Using sort_union(...)提示,说明准备使用Sort-Union索引合并的方式执行查询。 + - `Using index condition` 有些搜索条件中虽然出现了索引列,但却不能使用到索引 + - `Using index` 当我们的查询列表以及搜索条件中只包含属于某个索引的列,也就是在可以使用索引覆盖的情况下,在Extra列将会提示该额外信息 + - `Using index for group-by` 类似于访问表的 Using index 方式,Using index for group-by 表示 MySQL 发现了一个索引, 可以用来查 询 GROUP BY 或 DISTINCT 查询的所有列, 而不要额外搜索硬盘访问实际的表。 + + +## 查询不走索引优化 + +- WHERE字句的查询条件里有不等于号(WHERE column!=…),MYSQL将无法使用索引 +- 类似地,如果WHERE字句的查询条件里使用了函数(如:WHERE DAY(column)=…),MYSQL将无法使用索引 +- 在JOIN操作中(需要从多个数据表提取数据时),MYSQL只有在主键和外键的数据类型相同时才能使用索引,否则即使建立了索引也不会使用 +- 如果WHERE子句的查询条件里使用了比较操作符LIKE和REGEXP,MYSQL只有在搜索模板的第一个字符不是通配符的情况下才能使用索引。比如说,如果查询条件是LIKE 'abc%',MYSQL将使用索引;如果条件是LIKE '%abc',MYSQL将不使用索引。 +- 在ORDER BY操作中,MYSQL只有在排序条件不是一个查询条件表达式的情况下才使用索引。尽管如此,在涉及多个数据表的查询里,即使有索引可用,那些索引在加快ORDER BY操作方面也没什么作用。 +- 如果某个数据列里包含着许多重复的值,就算为它建立了索引也不会有很好的效果。比如说,如果某个数据列里包含了净是些诸如“0/1”或“Y/N”等值,就没有必要为它创建一个索引。 +- 索引有用的情况下就太多了。基本只要建立了索引,除了上面提到的索引不会使用的情况下之外,其他情况只要是使用在WHERE条件里,ORDER BY 字段,联表字段,一般都是有效的。 建立索引要的就是有效果。 不然还用它干吗? 如果不能确定在某个字段上建立的索引是否有效果,只要实际进行测试下比较下执行时间就知道。 +- 如果条件中有or(并且其中有or的条件是不带索引的),即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)。注意:要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引 +- 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引 +- 如果mysql估计使用全表扫描要比使用索引快,则不使用索引 + + +## 子查询优化 + +- MySQL 从 4.1 版本开始支持子查询,使用子查询进行 SELECT 语句嵌套查询,可以一次完成很多逻辑上需要多个步骤才能完成的 SQL 操作。 +- 子查询虽然很灵活,但是执行效率并不高。 +- 执行子查询时,MYSQL 需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响。 +- 优化: + - 可以使用连接查询(JOIN)代替子查询,连接查询时不需要建立临时表,其速度比子查询快。 + +## 其他查询优化 + +- 关联查询过程 + - 确保 ON 或者 using子句中的列上有索引 + - 确保任何的 groupby 和 orderby 中的表达式只涉及到一个表中的列。 +- count()函数优化 + - count()函数有一点需要特别注意:它是不统计值为NULL的字段的!所以:不能指定查询结果的某一列,来统计结果行数。即 count(xx column) 不太好。 + - 如果想要统计结果集,就使用 count(*),性能也会很好。 +- 分页查询(数据偏移量大的场景) + - 不允许跳页,只能上一页或者下一页 + - 使用 where 加上上一页 ID 作为条件(具体要看 explain 分析效果):`select xxx,xxx from test_table where id < '上页id分界值' order by id desc limit 20;` + +## 创表原则 + +- 所有字段均定义为 NOT NULL ,除非你真的想存 Null。因为表内默认值 Null 过多会影响优化器选择执行计划 + + +## 建立索引原则 + +- 使用区分度高的列作为索引,字段不重复的比例,区分度越高,索引树的分叉也就越多,一次性找到的概率也就越高。 +- 尽量使用字段长度小的列作为索引 +- 使用数据类型简单的列(int 型,固定长度) +- 选用 NOT NULL 的列。在MySQL中,含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂。你应该用0、一个特殊的值或者一个空串代替空值。 +- 尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。这样也可避免索引重复。 + + + +## 数据库结构优化 + +- 将字段很多的表分解成多个表 + - 对于字段较多的表,如果有些字段的使用频率很低,可以将这些字段分离出来形成新表。 + - 因为当一个表的数据量很大时,会由于使用频率低的字段的存在而变慢。 +- 增加中间表 + - 对于需要经常联合查询的表,可以建立中间表以提高查询效率。 + - 通过建立中间表,将需要通过联合查询的数据插入到中间表中,然后将原来的联合查询改为对中间表的查询。 +- 增加冗余字段 + - 设计数据表时应尽量遵循范式理论的规约,尽可能的减少冗余字段,让数据库设计看起来精致、优雅。但是,合理的加入冗余字段可以提高查询速度。 + + + +## 插入数据的优化(适用于 InnoDB) + +- 插入数据时,影响插入速度的主要是索引、唯一性校验、一次插入的数据条数等。 +- 开发环境情况下的考虑: + - 开发场景中,如果需要初始化数据,导入数据等一些操作,而且是开发人员进行处理的,可以考虑在插入数据之前,先禁用整张表的索引, + - 禁用索引使用 SQL:`ALTER TABLE table_name DISABLE KEYS;` + - 当导入完数据之后,重新让MySQL创建索引,并开启索引:`ALTER TABLE table_name ENABLE KEYS;` + - 如果表中有字段是有唯一性约束的,可以先禁用,然后在开启: + - 禁用唯一性检查的语句:`SET UNIQUE_CHECKS = 0;` + - 开启唯一性检查的语句:`SET UNIQUE_CHECKS = 1;` + - 禁用外键检查(建议还是少量用外键,而是采用代码逻辑来处理) + - 插入数据之前执行禁止对外键的检查,数据插入完成后再恢复,可以提供插入速度。 + - 禁用:`SET foreign_key_checks = 0;` + - 开启:`SET foreign_key_checks = 1;` + - 使用批量插入数据 + - 禁止自动提交 + - 插入数据之前执行禁止事务的自动提交,数据插入完成后再恢复,可以提供插入速度。 + - 禁用:`SET autocommit = 0;` + - 开启:`SET autocommit = 1;` + - 插入数据之前执行禁止对外键的检查,数据插入完成后再恢复 + - 禁用:`SET foreign_key_checks = 0;` + - 开启:`SET foreign_key_checks = 1;` + + +## 服务器优化 + +- 好硬件大家都知道,这里没啥好说,如果是 MySQL 单独一台机子,那机子内存可以考虑分配 60%~70% 给 MySQL +- 通过优化 MySQL 的参数可以提高资源利用率,从而达到提高 MySQL 服务器性能的目的。 + - 可以看我整理的这篇文章: +- 由于 binlog 日志的读写频繁,可以考虑在 my.cnf 中配置,指定这个 binlog 日志到一个 SSD 硬盘上。 + + +## 锁相关 + +InnoDB支持事务;InnoDB 采用了行级锁。也就是你需要修改哪行,就可以只锁定哪行。 +在 Mysql 中,行级锁并不是直接锁记录,而是锁索引。索引分为主键索引和非主键索引两种,如果一条sql 语句操作了主键索引,Mysql 就会锁定这条主键索引;如果一条语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引。 +InnoDB 行锁是通过给索引项加锁实现的,如果没有索引,InnoDB 会通过隐藏的聚簇索引来对记录加锁。也就是说:如果不通过索引条件检索数据,那么InnoDB将对表中所有数据加锁,实际效果跟表锁一样。因为没有了索引,找到某一条记录就得扫描全表,要扫描全表,就得锁定表。 + + +数据库的增删改操作默认都会加排他锁,而查询不会加任何锁。 + +排他锁:对某一资源加排他锁,自身可以进行增删改查,其他人无法进行任何操作。语法为: +select * from table for update; + +共享锁:对某一资源加共享锁,自身可以读该资源,其他人也可以读该资源(也可以再继续加共享锁,即 共享锁可多个共存),但无法修改。 +要想修改就必须等所有共享锁都释放完之后。语法为: +select * from table lock in share mode; + + + +## 资料 + +- +- +- +- +- +- +- +- <> +- <> +- <> +- <> +- <> \ No newline at end of file diff --git a/Mysql-Test.md b/markdown-file/Mysql-Test.md similarity index 54% rename from Mysql-Test.md rename to markdown-file/Mysql-Test.md index 4a6edfb9..f18d3f0f 100644 --- a/Mysql-Test.md +++ b/markdown-file/Mysql-Test.md @@ -47,6 +47,8 @@ - `--debug-info` 代表要额外输出 CPU 以及内存的相关信息。 - `--only-print` 打印压力测试的时候 mysqlslap 到底做了什么事,通过 sql 语句方式告诉我们。 +------------------------------------------------------------------- + ## sysbench 工具 @@ -148,6 +150,8 @@ Threads fairness: events (avg/stddev): 2748.6000/132.71 --总处理事件数/标准偏差 execution time (avg/stddev): 119.9907/0.00 --总执行时间/标准偏差 +------------------------------------------------------------------- + ## QPS 和 TPS 和说明 ### 基本概念 @@ -171,6 +175,348 @@ Threads fairness: - 每天300wPV的在单台机器上,这台机器需要多少QPS?对于这样的问题,假设每天80%的访问集中在20%的时间里,这20%时间叫做峰值时间。( 3000000 * 0.8 ) / (3600 * 24 * 0.2 ) = 139 (QPS). - 如果一台机器的QPS是58,需要几台机器来支持?答:139 / 58 = 3 +------------------------------------------------------------------- + +## Percona TPCC-MySQL 测试工具(优先推荐) + +- 可以较好地模拟真实测试结果数据 +- 官网主页: + +``` +TPC-C 是专门针对联机交易处理系统(OLTP系统)的规范,一般情况下我们也把这类系统称为业务处理系统。 +TPC-C是TPC(Transaction Processing Performance Council)组织发布的一个测试规范,用于模拟测试复杂的在线事务处理系统。其测试结果包括每分钟事务数(tpmC),以及每事务的成本(Price/tpmC)。 +在进行大压力下MySQL的一些行为时经常使用。 +``` + +### 安装 + +- 先确定本机安装过 MySQL +- 并且安装过:`yum install mysql-devel` + +``` +git clone https://github.com/Percona-Lab/tpcc-mysql +cd tpcc-mysql/src +make + +如果make没报错,就会在tpcc-mysql 根目录文件夹下生成tpcc二进制命令行工具tpcc_load、tpcc_start + +如果要同时支持 PgSQL 可以考虑:https://github.com/Percona-Lab/sysbench-tpcc +``` + +### 测试的几个表介绍 + +``` +tpcc-mysql的业务逻辑及其相关的几个表作用如下: +New-Order:新订单,主要对应 new_orders 表 +Payment:支付,主要对应 orders、history 表 +Order-Status:订单状态,主要对应 orders、order_line 表 +Delivery:发货,主要对应 order_line 表 +Stock-Level:库存,主要对应 stock 表 + +其他相关表: +客户:主要对应customer表 +地区:主要对应district表 +商品:主要对应item表 +仓库:主要对应warehouse表 +``` + +### 准备 + +- 测试阿里云 ECS 与 RDS 是否相通: +- 记得在 RDS 添加账号和给账号配置权限,包括:配置权限、数据权限(默认添加账号后都是没有开启的,还要自己手动开启) +- 还要添加内网 ECS 到 RDS 的白名单 IP 里面 +- 或者在 RDS 上开启外网访问设置,但是也设置 IP 白名单(访问 ip.cn 查看自己的外网 IP 地址,比如:120.85.112.97) +- RDS 的内网地址和外网地址不一样,要认真看。 + +``` +ping rm-wz9v0vej02ys79jbj.mysql.rds.aliyuncs.com + +mysql -h rm-wz9v0vej02ys79jbj.mysql.rds.aliyuncs.com -P 3306 -u myaccount -p + +输入密码:Aa123456 +``` + + + +``` +创库,名字为:TPCC: +CREATE DATABASE TPCC DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; + + +导入项目中的出初始化数据脚本: +创建表:create_table.sql +/usr/bin/mysql -h rm-wz9v0vej02ys79jbj.mysql.rds.aliyuncs.com -u myaccount -p tpcc < /root/tpcc-mysql/create_table.sql + +创建索引和外键:add_fkey_idx.sql +/usr/bin/mysql -h rm-wz9v0vej02ys79jbj.mysql.rds.aliyuncs.com -u myaccount -p tpcc < /root/tpcc-mysql/add_fkey_idx.sql +``` + + +### 测试 + +- 数据库:阿里云 RDS-MySQL-5.7-2C4G +- 测试机:阿里云 ECS-4C4G-CentOS7.6 +- 根据测试,不同的 ECS 测试机,不同的 RDS 测试结果有时候差距挺大的,这个很蛋疼。 + +- 需要注意的是 tpcc 默认会读取 /var/lib/mysql/mysql.sock 这个 socket 文件。因此,如果你的socket文件不在相应路径的话,可以做个软连接,或者通过TCP/IP的方式连接测试服务器 +- 准备数据: + +``` +cd /opt/tpcc-mysql +./tpcc_load -h rm-wz9v0vej02ys79jbj.mysql.rds.aliyuncs.com -P 3306 -d TPCC -u myaccount -p Aa123456 -w 80 +-w 80 表示创建 80 个仓库数据 +这个过程花费时间还是挺长的,建议测试机是高性能计算型。2CPU 差不多要 8h,你自己估量下。 +我这边 RDS 监控中,曲线上每秒 insert 差不多在 2W 差不多,如果你没有这个数,速度可能就很慢了。 +我这边差不多用了 2.5h 完成数据准备。 + + +插入过程 RDS-2C4G 的监控情况: +CPU利用率 24% +内存 30% ~ 40% (随着数据增加而增大) +连接数:1% +IOPS:9% +已使用存储空间:5.5G ~ 10G + +要模拟出够真实的数据,仓库不要太少,一般要大于 100, +下面是基于 80 个库的最终数据: + +select count(*) from customer; + 2400000 +select count(*) from district; + 800 +select count(*) from history; + 2400000 +select count(*) from item; + 100000 +select count(*) from new_orders; + 720000 +select count(*) from order_line; + 23996450 +select count(*) from orders; + 2400000 +select count(*) from stock; + 8000000 +select count(*) from warehouse; + 80 +``` + +- 开始测试: + +``` + +./tpcc_start -h rm-wz9v0vej02ys79jbj.mysql.rds.aliyuncs.com -P 3306 -d TPCC -u myaccount -p Aa123456 -w 80 -c 200 -r 300 -l 1800 -f /opt/mysql_tpcc_100_20190325 + +-w 100 表示 100 个仓库数据 +-c 200 表示并发 200 个线程 +-r 300 表示预热 300 秒 +-l 1800 表示持续压测 1800 秒 +``` + + +### 报表 + + +``` + +188.000 TpmC +TpmC结果值(每分钟事务数,该值是第一次统计结果中的新订单事务数除以总耗时分钟数,例如本例中是:372/2=186) +tpmC值在国内外被广泛用于衡量计算机系统的事务处理能力 +``` + +- RDS-2C4G-80个仓库结果: +- CPU:100%,内存:34%,连接数:17%,IOPS:62%,磁盘空间:20G + + +``` +1780, trx: 979, 95%: 1849.535, 99%: 2402.613, max_rt: 3401.947, 986|3248.772, 98|698.821, 103|4202.110, 101|4547.416 +1790, trx: 1021, 95%: 1898.903, 99%: 2700.936, max_rt: 3848.142, 999|3150.117, 100|500.740, 102|3600.104, 100|5551.834 +1800, trx: 989, 95%: 1899.472, 99%: 2847.899, max_rt: 4455.064, 989|3049.921, 101|699.144, 97|3599.021, 102|5151.141 + +STOPPING THREADS........................................................................................................................................................................................................ + + + [0] sc:2 lt:174378 rt:0 fl:0 avg_rt: 1192.8 (5) + [1] sc:253 lt:173935 rt:0 fl:0 avg_rt: 542.7 (5) + [2] sc:4726 lt:12712 rt:0 fl:0 avg_rt: 144.7 (5) + [3] sc:0 lt:17435 rt:0 fl:0 avg_rt: 3029.8 (80) + [4] sc:0 lt:17435 rt:0 fl:0 avg_rt: 3550.7 (20) + in 1800 sec. + + + [0] sc:2 lt:174378 rt:0 fl:0 + [1] sc:254 lt:174096 rt:0 fl:0 + [2] sc:4726 lt:12712 rt:0 fl:0 + [3] sc:0 lt:17437 rt:0 fl:0 + [4] sc:0 lt:17435 rt:0 fl:0 + + (all must be [OK]) + [transaction percentage] + Payment: 43.45% (>=43.0%) [OK] + Order-Status: 4.35% (>= 4.0%) [OK] + Delivery: 4.35% (>= 4.0%) [OK] + Stock-Level: 4.35% (>= 4.0%) [OK] + [response time (at least 90% passed)] + New-Order: 0.00% [NG] * + Payment: 0.15% [NG] * + Order-Status: 27.10% [NG] * + Delivery: 0.00% [NG] * + Stock-Level: 0.00% [NG] * + + + 5812.667 TpmC +``` + +- 升级:RDS-4C8G-80个仓库结果 +- CPU:100%,内存:55%,连接数:10%,IOPS:20%,磁盘空间:25G + +``` +1780, trx: 2303, 95%: 796.121, 99%: 1099.640, max_rt: 1596.883, 2293|2249.288, 232|256.393, 230|1694.050, 235|2550.775 +1790, trx: 2336, 95%: 798.030, 99%: 1093.403, max_rt: 1547.840, 2338|2803.739, 234|305.185, 232|1799.869, 228|2453.748 +1800, trx: 2305, 95%: 801.381, 99%: 1048.528, max_rt: 1297.465, 2306|1798.565, 229|304.329, 227|1649.609, 233|2549.599 + +STOPPING THREADS........................................................................................................................................................................................................ + + + [0] sc:7 lt:406567 rt:0 fl:0 avg_rt: 493.7 (5) + [1] sc:10485 lt:395860 rt:0 fl:0 avg_rt: 240.1 (5) + [2] sc:24615 lt:16045 rt:0 fl:0 avg_rt: 49.4 (5) + [3] sc:0 lt:40651 rt:0 fl:0 avg_rt: 1273.6 (80) + [4] sc:0 lt:40656 rt:0 fl:0 avg_rt: 1665.3 (20) + in 1800 sec. + + + [0] sc:7 lt:406569 rt:0 fl:0 + [1] sc:10487 lt:396098 rt:0 fl:0 + [2] sc:24615 lt:16045 rt:0 fl:0 + [3] sc:0 lt:40655 rt:0 fl:0 + [4] sc:0 lt:40659 rt:0 fl:0 + + (all must be [OK]) + [transaction percentage] + Payment: 43.46% (>=43.0%) [OK] + Order-Status: 4.35% (>= 4.0%) [OK] + Delivery: 4.35% (>= 4.0%) [OK] + Stock-Level: 4.35% (>= 4.0%) [OK] + [response time (at least 90% passed)] + New-Order: 0.00% [NG] * + Payment: 2.58% [NG] * + Order-Status: 60.54% [NG] * + Delivery: 0.00% [NG] * + Stock-Level: 0.00% [NG] * + + + 13552.467 TpmC +``` + + +- 升级:RDS-8C16G-80个仓库结果 +- CPU:100%,内存:35%,连接数:5%,IOPS:18%,磁盘空间:30G + +``` +1780, trx: 4502, 95%: 398.131, 99%: 501.634, max_rt: 772.128, 4473|740.073, 446|183.361, 448|1042.264, 442|1302.569 +1790, trx: 4465, 95%: 398.489, 99%: 541.424, max_rt: 803.659, 4476|845.313, 448|152.917, 450|997.319, 454|1250.160 +1800, trx: 4506, 95%: 397.774, 99%: 501.334, max_rt: 747.074, 4508|701.625, 453|108.619, 450|1052.293, 451|1107.277 + +STOPPING THREADS........................................................................................................................................................................................................ + + + [0] sc:20 lt:803738 rt:0 fl:0 avg_rt: 240.5 (5) + [1] sc:13844 lt:789535 rt:0 fl:0 avg_rt: 128.5 (5) + [2] sc:54560 lt:25817 rt:0 fl:0 avg_rt: 22.1 (5) + [3] sc:0 lt:80372 rt:0 fl:0 avg_rt: 739.8 (80) + [4] sc:0 lt:80378 rt:0 fl:0 avg_rt: 771.1 (20) + in 1800 sec. + + + [0] sc:20 lt:803747 rt:0 fl:0 + [1] sc:13845 lt:789916 rt:0 fl:0 + [2] sc:54561 lt:25817 rt:0 fl:0 + [3] sc:0 lt:80377 rt:0 fl:0 + [4] sc:0 lt:80381 rt:0 fl:0 + + (all must be [OK]) + [transaction percentage] + Payment: 43.47% (>=43.0%) [OK] + Order-Status: 4.35% (>= 4.0%) [OK] + Delivery: 4.35% (>= 4.0%) [OK] + Stock-Level: 4.35% (>= 4.0%) [OK] + [response time (at least 90% passed)] + New-Order: 0.00% [NG] * + Payment: 1.72% [NG] * + Order-Status: 67.88% [NG] * + Delivery: 0.00% [NG] * + Stock-Level: 0.00% [NG] * + + + 26791.934 TpmC +``` + + +- 升级:RDS-16C64G-80个仓库结果 +- CPU:100%,内存:18%,连接数:2%,IOPS:10%,磁盘空间:40G + +``` +1780, trx: 8413, 95%: 203.560, 99%: 279.322, max_rt: 451.010, 8414|441.849, 841|92.900, 839|583.340, 843|644.276 +1790, trx: 8269, 95%: 204.599, 99%: 282.602, max_rt: 444.075, 8262|412.414, 827|91.551, 831|665.421, 824|616.396 +1800, trx: 8395, 95%: 202.285, 99%: 255.026, max_rt: 436.136, 8404|446.292, 839|87.081, 839|609.221, 842|697.509 + +STOPPING THREADS........................................................................................................................................................................................................ + + + [0] sc:37 lt:1532893 rt:0 fl:0 avg_rt: 124.8 (5) + [1] sc:36091 lt:1496111 rt:0 fl:0 avg_rt: 68.5 (5) + [2] sc:105738 lt:47555 rt:0 fl:0 avg_rt: 11.4 (5) + [3] sc:0 lt:153285 rt:0 fl:0 avg_rt: 404.6 (80) + [4] sc:0 lt:153293 rt:0 fl:0 avg_rt: 389.5 (20) + in 1800 sec. + + + [0] sc:37 lt:1532918 rt:0 fl:0 + [1] sc:36093 lt:1496868 rt:0 fl:0 + [2] sc:105739 lt:47556 rt:0 fl:0 + [3] sc:0 lt:153297 rt:0 fl:0 + [4] sc:0 lt:153298 rt:0 fl:0 + + (all must be [OK]) + [transaction percentage] + Payment: 43.47% (>=43.0%) [OK] + Order-Status: 4.35% (>= 4.0%) [OK] + Delivery: 4.35% (>= 4.0%) [OK] + Stock-Level: 4.35% (>= 4.0%) [OK] + [response time (at least 90% passed)] + New-Order: 0.00% [NG] * + Payment: 2.36% [NG] * + Order-Status: 68.98% [NG] * + Delivery: 0.00% [NG] * + Stock-Level: 0.00% [NG] * + + + 51097.668 TpmC +``` + + +- 几轮下来,最终数据量: + +``` +select count(*) from customer; + 2400000 +select count(*) from district; + 800 +select count(*) from history; + 5779395 +select count(*) from item; + 100000 +select count(*) from new_orders; + 764970 +select count(*) from order_line; + 57453708 +select count(*) from orders; + 5745589 +select count(*) from stock; + 8000000 +select count(*) from warehouse; + 80 +``` ## 资料 @@ -181,3 +527,4 @@ Threads fairness: - - - +- \ No newline at end of file diff --git a/Mysql-Tutorial.md b/markdown-file/Mysql-Tutorial.md similarity index 100% rename from Mysql-Tutorial.md rename to markdown-file/Mysql-Tutorial.md diff --git a/NFS.md b/markdown-file/NFS.md similarity index 100% rename from NFS.md rename to markdown-file/NFS.md diff --git a/markdown-file/NTP.md b/markdown-file/NTP.md new file mode 100644 index 00000000..79f61266 --- /dev/null +++ b/markdown-file/NTP.md @@ -0,0 +1,145 @@ +## NTP(Network Time Protocol)介绍 + + + +## NTP 安装 + +- 查看是否已安装: + - CentOS:`rpm -qa | grep ntp-*` + - Ubuntu:`dpkg -l | grep ntp-*` + +- 安装: + - CentOS 6/7:`sudo yum install -y ntp` + - Ubuntu:`sudo apt-get install -y ntp` + +## 配置阿里云 NTP(推荐) + +- 官网介绍: +- 配置文件介绍(记得先备份):`sudo vim /etc/ntp.conf` +- 注释掉以下默认的配置内容: + +``` +server 0.centos.pool.ntp.org iburst +server 1.centos.pool.ntp.org iburst +server 2.centos.pool.ntp.org iburst +server 3.centos.pool.ntp.org iburst +``` + +- 新增配置: + +``` nginx +ntp1.aliyun.com +ntp2.aliyun.com +ntp3.aliyun.com +ntp4.aliyun.com +ntp5.aliyun.com +ntp6.aliyun.com +ntp7.aliyun.com +``` + +- CentOS 6 + - 重启 NTP 服务:`sudo service ntpd start` + - 添加 NTP 自启动:`sudo chkconfig ntpd on` +- CentOS 7 + - 重启 NTP 服务:`sudo systemctl start ntpd.service` + - 添加 NTP 自启动:`sudo systemctl enable ntpd.service` + + +## NTP 服务器配置文件常用参数 + +- 世界上可以校对时间节点: +- 中国时间校对服务器节点: +- 配置文件介绍(记得先备份):`sudo vim /etc/ntp.conf` + + +![NTP 服务器配置文件常用参数](../images/NTP-a-1.jpg) + +- 该配置解释: +- 标注 1 是默认内容,我们这里进行了注释。 +- 标注 2 是新增内容,表示使用中国时间校对服务器节点地址。 + +``` nginx +server 0.cn.pool.ntp.org +server 1.cn.pool.ntp.org +server 2.cn.pool.ntp.org +server 3.cn.pool.ntp.org +``` + +- 我的配置如下 + ``` + driftfile /var/lib/ntp/drift +pidfile /var/run/ntpd.pid +logfile /var/log/ntp.log + + +# Access Control Support +restrict default kod nomodify notrap nopeer noquery +restrict -6 default kod nomodify notrap nopeer noquery +restrict 127.0.0.1 +restrict 192.168.0.0 mask 255.255.0.0 nomodify notrap nopeer noquery +restrict 172.16.0.0 mask 255.240.0.0 nomodify notrap nopeer noquery +restrict 100.64.0.0 mask 255.192.0.0 nomodify notrap nopeer noquery +restrict 10.0.0.0 mask 255.0.0.0 nomodify notrap nopeer noquery + + +# local clock +server 127.127.1.0 +fudge 127.127.1.0 stratum 10 + + +restrict ntp1.aliyun.com nomodify notrap nopeer noquery +restrict ntp1.cloud.aliyuncs.com nomodify notrap nopeer noquery +restrict ntp10.cloud.aliyuncs.com nomodify notrap nopeer noquery +restrict ntp11.cloud.aliyuncs.com nomodify notrap nopeer noquery +restrict ntp12.cloud.aliyuncs.com nomodify notrap nopeer noquery +restrict ntp2.aliyun.com nomodify notrap nopeer noquery +restrict ntp2.cloud.aliyuncs.com nomodify notrap nopeer noquery +restrict ntp3.aliyun.com nomodify notrap nopeer noquery +restrict ntp3.cloud.aliyuncs.com nomodify notrap nopeer noquery +restrict ntp4.aliyun.com nomodify notrap nopeer noquery +restrict ntp4.cloud.aliyuncs.com nomodify notrap nopeer noquery +restrict ntp5.aliyun.com nomodify notrap nopeer noquery +restrict ntp5.cloud.aliyuncs.com nomodify notrap nopeer noquery +restrict ntp6.aliyun.com nomodify notrap nopeer noquery +restrict ntp6.cloud.aliyuncs.com nomodify notrap nopeer noquery +restrict ntp7.cloud.aliyuncs.com nomodify notrap nopeer noquery +restrict ntp8.cloud.aliyuncs.com nomodify notrap nopeer noquery +restrict ntp9.cloud.aliyuncs.com nomodify notrap nopeer noquery + + +server ntp1.aliyun.com iburst minpoll 4 maxpoll 10 +server ntp1.cloud.aliyuncs.com iburst minpoll 4 maxpoll 10 +server ntp10.cloud.aliyuncs.com iburst minpoll 4 maxpoll 10 +server ntp11.cloud.aliyuncs.com iburst minpoll 4 maxpoll 10 +server ntp12.cloud.aliyuncs.com iburst minpoll 4 maxpoll 10 +server ntp2.aliyun.com iburst minpoll 4 maxpoll 10 +server ntp2.cloud.aliyuncs.com iburst minpoll 4 maxpoll 10 +server ntp3.aliyun.com iburst minpoll 4 maxpoll 10 +server ntp3.cloud.aliyuncs.com iburst minpoll 4 maxpoll 10 +server ntp4.aliyun.com iburst minpoll 4 maxpoll 10 +server ntp4.cloud.aliyuncs.com iburst minpoll 4 maxpoll 10 +server ntp5.aliyun.com iburst minpoll 4 maxpoll 10 +server ntp5.cloud.aliyuncs.com iburst minpoll 4 maxpoll 10 +server ntp6.aliyun.com iburst minpoll 4 maxpoll 10 +server ntp6.cloud.aliyuncs.com iburst minpoll 4 maxpoll 10 +server ntp7.cloud.aliyuncs.com iburst minpoll 4 maxpoll 10 +server ntp8.cloud.aliyuncs.com iburst minpoll 4 maxpoll 10 +server ntp9.cloud.aliyuncs.com iburst minpoll 4 maxpoll 10 +``` +- 启动服务: + - `sudo service ntpd stop`(改配置后,先停再启动) + - `sudo service ntpd start` +- 手动更新时间: + - `sudo ntpdate ntp1.aliyun.com` + +- 服务加到启动项 + - CentOS 系统:`sudo chkconfig ntpd on` + - Ubuntu 系统 + - `sudo apt-get install -y sysv-rc-conf ` + - `sudo sysv-rc-conf ntpd on` + +## NTP 资料 + +- +- +- diff --git a/Nexus-Install-And-Settings.md b/markdown-file/Nexus-Install-And-Settings.md similarity index 85% rename from Nexus-Install-And-Settings.md rename to markdown-file/Nexus-Install-And-Settings.md index db749f20..c35bffb8 100644 --- a/Nexus-Install-And-Settings.md +++ b/markdown-file/Nexus-Install-And-Settings.md @@ -58,9 +58,9 @@ - 修改默认端口:`vim /usr/program/nexus2.11.4/conf/nexus.properties`,修改该值:application-port=8081 - 下载远程中央库的索引到服务器 - - ![Nexus 配置](images/Nexus-Install-And-Settings-a-1.jpg) + - ![Nexus 配置](../images/Nexus-Install-And-Settings-a-1.jpg) - 如上图标注 4 所示,把默认是 `False` 改为 `True` - - ![Nexus 配置](images/Nexus-Install-And-Settings-a-2.gif) + - ![Nexus 配置](../images/Nexus-Install-And-Settings-a-2.gif) - 如上图 gif 所示,创建任务开始进行索引下载。需要特别提醒的是,如果你的私服是虚拟机,那得保证你分配的硬盘足够大,别像我一样吝啬只给 10 G(现在还剩下 1.9 G),结果报:**设备上没有空间** - 项目上配置链接连接私服(下面内容涉及到 maven 的基础知识,请自行私下学习): - 对项目独立设置: @@ -138,7 +138,7 @@ http://192.168.1.73:8081/repository/maven-snapshots/ - aliyun-maven + maven-aliyun aliyun maven http://maven.aliyun.com/nexus/content/groups/public/ central @@ -275,6 +275,39 @@ - 重启服务:`/usr/program/nexus2.11.4/bin/nexus start` +## Nexus3 功能 + +#### 搜索 + +- 搜索依赖(支持匹配符): + +#### 创建角色 + +- 地址: + +#### 创建用户 + +- 地址: + +#### 设置仓库 + +- 仓库常见类型: + - proxy,“代理”类型,代理请求官方仓库,并缓存在本地,图中maven-central即是 + - hosted,“私有”仓库,公司组织内部自由仓库,比如存储自己的jar包等,maven-releases、maven-snapshots即是 + - group,“组”,逻辑上的,可以把几个仓库划归到某个组,对外统一的地址访问,maven-public即是,它包含了另外3个 +- 仓库地址: +- 设置 maven-central 的 proxy 为官网默认地址: + - proxy 的意义:当客户端访问中央库的时候,如果 Nexus 没有该依赖,则先通过 Proxy 地址下载到 Nexus 仓库,然后客户端再从 Nexus 服务器下载到本地。 +- 一般建议新增一个 maven-aliyun 的 proxy 类型仓库,proxy 地址是: + - 然后在 maven-public 设置 Member repositories 的时候确保 maven-aliyun 排序大于 maven-central 即可。 +- 设置 maven-public,集成其他仓库: + - 一般 Member repositories 的排序建议是:maven-releases、maven-snapshots、maven-aliyun、maven-central +- 如果需要设置 npm 的仓库可以看这篇文章:[Nexus OSS3创建npm 私服](https://wendyeq.me/2016/11/24/npm-registry-in-nexus-oss-3/) + +#### 设置 task + +- 地址: + ## 资料 - @@ -287,3 +320,5 @@ - - - +- +- diff --git a/Nginx-Install-And-Settings.md b/markdown-file/Nginx-Install-And-Settings.md similarity index 58% rename from Nginx-Install-And-Settings.md rename to markdown-file/Nginx-Install-And-Settings.md index 01789457..6a5ffb0c 100644 --- a/Nginx-Install-And-Settings.md +++ b/markdown-file/Nginx-Install-And-Settings.md @@ -44,16 +44,86 @@ ## Nginx 的 Docker 部署 -- 预设好目录,在宿主机上创建下面目录:`mkdir -p /data/nginx/html /data/nginx/conf.d /data/nginx/logs /data/nginx/conf` -- 先准备好你的 nginx.conf 文件,存放在宿主机的:/data/nginx/conf 目录下,等下需要映射。 +- 预设好目录,在宿主机上创建下面目录:`mkdir -p /data/docker/nginx/logs /data/docker/nginx/conf` +- **重点**:先准备好你的 nginx.conf 文件,存放在宿主机的:`vim /data/docker/nginx/conf/nginx.conf` 目录下,等下需要映射。 + +``` +worker_processes 1; + +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + + sendfile on; + + keepalive_timeout 65; + + server { + listen 80; + server_name localhost 127.0.0.1 193.112.221.203 youmeek.com; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } + } +} +``` + +- 官网镜像: - 下载镜像:`docker pull nginx:1.12.2` -- 运行容器:`docker run --name cas-nginx -p 80:80 -v /data/nginx/html:/usr/share/nginx/html:ro -v /data/nginx/conf.d:/etc/nginx/conf.d -v /data/nginx/logs:/var/log/nginx -v /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx:1.12.2` -- 重新加载配置(目前测试无效,只能重启服务):`docker exec -it cas-nginx nginx -s reload` -- 停止服务:`docker exec -it cas-nginx nginx -s stop` 或者:`docker stop cas-nginx` -- 重新启动服务:`docker restart cas-nginx` +- 运行容器:`docker run --name youmeek-nginx -p 80:80 -v /data/docker/nginx/logs:/var/log/nginx -v /data/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx:1.12.2` +- 重新加载配置(目前测试无效,只能重启服务):`docker exec -it youmeek-nginx nginx -s reload` +- 停止服务:`docker exec -it youmeek-nginx nginx -s stop` 或者:`docker stop youmeek-nginx` +- 重新启动服务:`docker restart youmeek-nginx` + + +------------------------------------------------------------------- + +## YUM 安装(版本一般滞后半年左右) -## Nginx 源码编译安装 +- 安装:`yum install -y nginx`,同时增加了一个 nginx 用户组和用户 +- 默认配置文件位置:`vim /etc/nginx/nginx.conf` +- 其他配置文件位置:`cd /etc/nginx/conf.d/` +- 模块配置文件位置:`cd /usr/share/nginx/modules/` +- 默认 HTML 静态文件位置:`cd /usr/share/nginx/html` +- log 存放目录:`cd /var/log/nginx/` +- 状态:`systemctl status nginx` +- 启动:`systemctl start nginx` +- 启动:`systemctl stop nginx` +- 刷新配置:`nginx -s reload` +- 查看版本和 YUM 自带的模块:`nginx -V` + + +------------------------------------------------------------------- + +## Nginx 源码编译安装(带 Prometheus 模块) + +``` +./configure \ +--prefix=/usr/local/nginx \ +--pid-path=/var/local/nginx/nginx.pid \ +--lock-path=/var/lock/nginx/nginx.lock \ +--error-log-path=/var/log/nginx/error.log \ +--http-log-path=/var/log/nginx/access.log \ +--with-http_gzip_static_module \ +--http-client-body-temp-path=/var/temp/nginx/client \ +--http-proxy-temp-path=/var/temp/nginx/proxy \ +--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \ +--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \ +--with-http_ssl_module \ +--with-http_stub_status_module \ +--http-scgi-temp-path=/var/temp/nginx/scgi \ +--add-module=/usr/local/nginx-module-vts +``` + + +## Nginx 源码编译安装(带监控模块) - 官网下载最新稳定版本 **1.8.1**,大小:814K - 官网安装说明: @@ -69,46 +139,58 @@ - 进入解压后目录:`cd nginx-1.8.1/` - 编译配置: - ``` ini - ./configure \ - --prefix=/usr/local/nginx \ - --pid-path=/var/local/nginx/nginx.pid \ - --lock-path=/var/lock/nginx/nginx.lock \ - --error-log-path=/var/log/nginx/error.log \ - --http-log-path=/var/log/nginx/access.log \ - --with-http_gzip_static_module \ - --http-client-body-temp-path=/var/temp/nginx/client \ - --http-proxy-temp-path=/var/temp/nginx/proxy \ - --http-fastcgi-temp-path=/var/temp/nginx/fastcgi \ - --http-uwsgi-temp-path=/var/temp/nginx/uwsgi \ - --with-http_ssl_module \ - --http-scgi-temp-path=/var/temp/nginx/scgi - ``` - - - 编译:`make` - - 安装:`make install` +``` ini +./configure \ +--prefix=/usr/local/nginx \ +--pid-path=/var/local/nginx/nginx.pid \ +--lock-path=/var/lock/nginx/nginx.lock \ +--error-log-path=/var/log/nginx/error.log \ +--http-log-path=/var/log/nginx/access.log \ +--with-http_gzip_static_module \ +--http-client-body-temp-path=/var/temp/nginx/client \ +--http-proxy-temp-path=/var/temp/nginx/proxy \ +--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \ +--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \ +--with-http_ssl_module \ +--with-http_stub_status_module \ +--http-scgi-temp-path=/var/temp/nginx/scgi +``` + +- 编译:`make` +- 安装:`make install` - 启动 Nginx - - 先检查是否在 /usr/local 目录下生成了 Nginx 等相关文件:`cd /usr/local/nginx;ll`,正常的效果应该是显示这样的: - - ``` nginx - drwxr-xr-x. 2 root root 4096 3月 22 16:21 conf - drwxr-xr-x. 2 root root 4096 3月 22 16:21 html - drwxr-xr-x. 2 root root 4096 3月 22 16:21 sbin - ``` - - - 停止防火墙:`service iptables stop` - - 或是把 80 端口加入到的排除列表: - - `sudo iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT` - - `sudo service iptables save` - - `sudo service iptables restart` - - 启动:`/usr/local/nginx/sbin/nginx`,启动完成 shell 是不会有输出的 - - 检查 时候有 Nginx 进程:`ps aux | grep nginx`,正常是显示 3 个结果出来 - - 检查 Nginx 是否启动并监听了 80 端口:`netstat -ntulp | grep 80` - - 访问:`192.168.1.114`,如果能看到:`Welcome to nginx!`,即可表示安装成功 - - 检查 Nginx 启用的配置文件是哪个:`/usr/local/nginx/sbin/nginx -t` - - 刷新 Nginx 配置后重启:`/usr/local/nginx/sbin/nginx -s reload` - - 停止 Nginx:`/usr/local/nginx/sbin/nginx -s stop` - - 如果访问不了,或是出现其他信息看下错误立即:`vim /var/log/nginx/error.log` + - 先检查是否在 /usr/local 目录下生成了 Nginx 等相关文件:`cd /usr/local/nginx;ll`,正常的效果应该是显示这样的: + +``` nginx +drwxr-xr-x. 2 root root 4096 3月 22 16:21 conf +drwxr-xr-x. 2 root root 4096 3月 22 16:21 html +drwxr-xr-x. 2 root root 4096 3月 22 16:21 sbin +``` + +- 如果要检查刚刚编译的哪些模块,可以:`nginx -V` + +``` +nginx version: nginx/1.8.0 +built by gcc 4.4.7 20120313 (Red Hat 4.4.7-18) (GCC) +built with OpenSSL 1.0.1e-fips 11 Feb 2013 +TLS SNI support enabled +configure arguments: --user=nginx --group=nginx --prefix=/usr/local/nginx --pid-path=/usr/local/nginx/run/nginx.pid --lock-path=/usr/local/nginx/lock/nginx.lock --with-http_ssl_module --with-http_dav_module --with-http_flv_module --with-http_gzip_static_module --with-http_stub_status_module +``` + + +- 停止防火墙:`service iptables stop` + - 或是把 80 端口加入到的排除列表: + - `sudo iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT` + - `sudo service iptables save` + - `sudo service iptables restart` +- 启动:`/usr/local/nginx/sbin/nginx`,启动完成 shell 是不会有输出的 +- 检查 时候有 Nginx 进程:`ps aux | grep nginx`,正常是显示 3 个结果出来 +- 检查 Nginx 是否启动并监听了 80 端口:`netstat -ntulp | grep 80` +- 访问:`192.168.1.114`,如果能看到:`Welcome to nginx!`,即可表示安装成功 +- 检查 Nginx 启用的配置文件是哪个:`/usr/local/nginx/sbin/nginx -t` +- 刷新 Nginx 配置后重启:`/usr/local/nginx/sbin/nginx -s reload` +- 停止 Nginx:`/usr/local/nginx/sbin/nginx -s stop` +- 如果访问不了,或是出现其他信息看下错误立即:`vim /var/log/nginx/error.log` ## 把 Nginx 添加到系统服务中 @@ -209,6 +291,46 @@ exit $RETVAL - 重启服务:`service nginx restart` +## Nginx 无缝升级 + +- 使用新的参数`configure`后执行`make`重新编译,注意之后不要执行`make install`.新构建的Nginx会在`objs`目录下 +- 备份旧的Nginx `cp 老的nginx目录/sbin/nginx 老的nginx目录/sbin/nginx.old` +- 复制新的Nginx `cp ./objs/nginx 老的nginx目录/sbin/`,可能提示Nginx被占用,如果是则强制覆盖即可. +- 检查下Makefile的更新指令 `cat Makefile`,检查下路径是否匹配,一般没什么问题毕竟是根据你的参数生成的文件. +```bash +upgrade: + /usr/local/nginx/sbin/nginx -t + + kill -USR2 `cat /var/local/nginx/nginx.pid` + sleep 1 + test -f /var/local/nginx/nginx.pid.oldbin + + kill -QUIT `cat /var/local/nginx/nginx.pid.oldbin` +``` +- 更新 `make upgrade` + + +## 为 Nginx 添加 basic_auth + +``` +yum install httpd-tools + +htpasswd -c /opt/nginx-auth/passwd.db myusername,回车之后输入两次密码 + + +server { + ... + + location / { + auth_basic "please input you user name and password"; + auth_basic_user_file /opt/nginx-auth/passwd.db; + .... + } +} + +``` + + ## Nginx 全局变量 - $arg_PARAMETER #这个变量包含GET请求中,如果有变量PARAMETER时的值。 @@ -449,7 +571,7 @@ http { - 教程: - SSL For Free: - 配置要点其实就是下面该图: -- ![免费申请 SSL 证书渠道](images/Nginx-SSL-a-1.jpg) +- ![免费申请 SSL 证书渠道](../images/Nginx-SSL-a-1.jpg) - 一般你会下载下面两个文件:`certificate.crt`,`private.key` - 如果你需要把 crt 和 key 的证书转换成 keystore(如果你有这个需求的话) - 从 key 和 crt 生成 pkcs12 格式的 keystore,生成过程会让人你输入密码,这个密码下面会用到,我这里假设输入 123456 @@ -497,6 +619,232 @@ http { ``` +- 最新版本的 Nginx SSL 配置 + +``` +listen 443 ssl; + +ssl_certificate /opt/jar/ssl/server.crt; +ssl_certificate_key /opt/jar/ssl/server.key; + +ssl_session_timeout 5m; +ssl_protocols TLSv1 TLSv1.1 TLSv1.2; +ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; +ssl_prefer_server_ciphers on; +``` + +---------------------------------------------------------------------- + +## Nginx 压力测试 + +- AB 测试工具安装:`yum install -y httpd-tools` +- 使用: + +``` +ab -n 1000 -c 100 http://www.baidu.com/ + +-n 总的请求数 +-c 单个时刻并发数 +``` + + +- 压测结果: + + +``` +This is ApacheBench, Version 2.3 <$Revision: 1430300 $> +Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ +Licensed to The Apache Software Foundation, http://www.apache.org/ + +Benchmarking juejin.im (be patient) +Completed 100 requests +Completed 200 requests +Completed 300 requests +Completed 400 requests +Completed 500 requests +Completed 600 requests +Completed 700 requests +Completed 800 requests +Completed 900 requests +Completed 1000 requests +Finished 1000 requests + + +Server Software: nginx +Server Hostname: juejin.im +Server Port: 443 +SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256 + +Document Path: / +Document Length: 271405 bytes + +Concurrency Level: 100(并发数:100) +Time taken for tests: 120.042 seconds(一共用了 120 秒) +Complete requests: 1000(总的请求数:1000) +Failed requests: 0(失败的请求次数) +Write errors: 0 +Total transferred: 271948000 bytes +HTML transferred: 271405000 bytes +Requests per second: 8.33 [#/sec] (mean)(QPS 系统吞吐量,平均每秒请求数,计算公式 = 总请求数 / 总时间数) +Time per request: 12004.215 [ms] (mean)(毫秒,平均每次并发 100 个请求的处理时间) +Time per request: 120.042 [ms] (mean, across all concurrent requests)(毫秒,并发 100 下,平均每个请求处理时间) +Transfer rate: 2212.34 [Kbytes/sec] received(平均每秒网络流量) + +Connection Times (ms) + min mean[+/-sd] median max +Connect: 57 159 253.6 77 1002 +Processing: 1139 11570 2348.2 11199 36198 +Waiting: 156 1398 959.4 1279 22698 +Total: 1232 11730 2374.1 11300 36274 + +Percentage of the requests served within a certain time (ms) + 50% 11300 + 66% 11562 + 75% 11863 + 80% 12159 + 90% 13148 + 95% 15814 + 98% 18882 + 99% 22255 + 100% 36274 (longest request) +``` + + +---------------------------------------------------------------------- + + +## Nginx 常规优化 + +#### 增加工作线程数和并发连接数 + +- 修改参数:`worker_processes 1;` +- 该参数是指:nginx 要开启的工作进程数(worker process),默认是 1,一把你不需要修改。(除了工作进程,还有一种 master process 的概念) +- 但是如果请求数比较多,一般推荐最大是修改成 CPU 的内核数等同的值,以增加能力。 +- 修改 events 参数 + +``` +events { + # 每一个进程可以打开的最大连接数(这个参数是受限制于系统参数的,默认是 1024)(进程数是上面 worker_processes 决定的) + worker_connections 1024; + # 可以一次建立多个连接 + multi_accept on; + # epoll 模式效率最高 + use epoll; +} +``` + +#### 启动长连接 + +``` +http { + sendfile on; # 减少文件在应用和内核之间的拷贝 + tcp_nopush on; # 当数据包达到一定大小再发送 + + keepalive_timeout 65; + + upstream tomcatCluster { + server 192.168.1.114:8080; + server 192.168.1.114:8081; + keepalive 300; # 300 个长连接 + } + +} +``` + +#### 启用缓存和压缩 + +``` +http { + gzip on; + gzip_buffers 8 16k; # 这个限制了nginx不能压缩大于128k的文件 + gzip_min_length 512; # 单位byte + gzip_disable "MSIE [1-6]\.(?!.*SV1)"; + gzip_http_version 1.1; # 1.0 的版本可能会有问题 + gzip_types text/plain text/css application/javascript application/x-javascript application/json application/xml; +} +``` + +#### 操作系统优化(机器好点的时候) + +###### 修改 sysctl 参数 + +- 修改配置文件:`vim /etc/sysctl.conf` + +``` +net.ipv4.tcp_fin_timeout = 10 #保持在FIN-WAIT-2状态的时间,使系统可以处理更多的连接。此参数值为整数,单位为秒。 +net.ipv4.tcp_tw_reuse = 1 #开启重用,允许将TIME_WAIT socket用于新的TCP连接。默认为0,表示关闭。 +net.ipv4.tcp_tw_recycle = 0 #开启TCP连接中TIME_WAIT socket的快速回收。默认值为0,表示关闭。 +net.ipv4.tcp_syncookies = 1 #开启SYN cookie,出现SYN等待队列溢出时启用cookie处理,防范少量的SYN攻击。默认为0,表示关闭。 +net.core.somaxconn = 1024 #定义了系统中每一个端口最大的监听队列的长度, 对于一个经常处理新连接的高负载 web服务环境来说,默认值为128,偏小。 +``` + +- 刷新 sysctl 配置:`sysctl -p` + +###### 修改 limits 参数 + +- ElasticSearch 一般也是要修改该参数 +- 修改配置文件:`vim /etc/security/limits.conf` + +``` +* soft nofile 262144 +* hard nofile 262144 +* soft core unlimited +* soft stack 262144 +``` + +---------------------------------------------------------------------- + +## Nginx 监控模块 + +- 如果你需要监控 nginx 情况可以安装的加入这个模块 http_stub_status_module: + +``` ini +./configure \ +--prefix=/usr/local/nginx \ +--pid-path=/var/local/nginx/nginx.pid \ +--lock-path=/var/lock/nginx/nginx.lock \ +--error-log-path=/var/log/nginx/error.log \ +--http-log-path=/var/log/nginx/access.log \ +--with-http_gzip_static_module \ +--http-client-body-temp-path=/var/temp/nginx/client \ +--http-proxy-temp-path=/var/temp/nginx/proxy \ +--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \ +--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \ +--with-http_ssl_module \ +--http-scgi-temp-path=/var/temp/nginx/scgi \ +--with-http_stub_status_module +``` + +- 然后在 nginx.conf 文件的 location 区域增加:stub_status on; + + +```ini +location /nginx_status { + allow 127.0.0.1; + deny all; + stub_status on; + access_log off; +} +``` + +- 当你访问:http://127.0.0.1/nginx_status,会得到类似下面的结果 +- 其中配置的 `allow 127.0.0.1;` 表示只允许本机访问:http://127.0.0.1/nginx_status 才能看到 + - 所以我们也可以通过 curl 访问本机看到结果,不一定要对外开放。 +- `deny all;` 除了被允许的,其他所有人都不可以访问 + +``` +Active connections: 1 +server accepts handled requests + 3 6 9 +Reading: 0 Writing: 5 Waiting: 0 +``` + +- Active connections: 当前活动连接数,包含 waiting 的连接(最常需要看的就是这个参数) +- Server accepts handled requests: Nginx总共处理了 3 个连接,成功创建 6 次握手(证明中间没有失败的),总共处理了 9 个请求. +- Reading: Nginx 读取到客户端的 Header 信息数,如果很大,说明现在很多请求正在过来 +- Writing: Nginx 返回给客户端的 Header 信息数,如果很大,说明现在又很多请求正在响应 +- Waiting: 开启keep-alive的情况下,这个值等于 active – (reading + writing),意思就是 Nginx 已经处理完成,正在等候下一次请求指令的驻留连接. +- 所以,在访问效率高,请求很快被处理完毕的情况下,Waiting数比较多是正常的。**如果reading + writing数较多,则说明并发访问量非常大,正在处理过程中** ## Nginx 配置文件常用配置积累 @@ -551,9 +899,31 @@ location ~ .*$ { } ``` +### 链接 aa 下,查询参数包含 bb +- 这里必须使用:IF,但是 IF 是不被推荐的:[If Is Evil](https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/) +``` +location /aa/ { + if ( $args ~* '(.*bb.*)' ) { + return 601; + } +} +``` + +``` +location /aa/ { + if ($args ~ tag=bb){ + return 601; + } +} +``` + + + +------------------------------------------------------------------- + ### HTTP 服务,绑定多个域名 @@ -585,7 +955,13 @@ location ~ .*$ { ### Nginx 自动分割日志文件 - +- 在 [Tomcat 安装和配置、优化](Tomcat-Install-And-Settings.md) 文章已经使用了 cronolog,这里也借用 cronolog 来实现分割。具体安装看文章。 +- 创建目录:`mkdir -p /data/nginx/log/logs` +- 创建命名管道:`mkfifo /data/nginx/log/access_log.log` +- 配置 cronolog(按天):`nohup cat /data/nginx/log/access_log.log | /usr/sbin/cronolog /data/nginx/log/logs/access-%Y-%m-%d.log &` +- 配置 cronolog(按月):`nohup cat /data/nginx/log/access_log.log | /usr/sbin/cronolog /data/nginx/log/logs/access-%Y-%m.log &` +- 编辑 nginx 配置文件,配置 log 位置:`access_log /data/nginx/log/access_log.log;` +- 重启 nginx,最终可以在 /data/nginx/log/logs 目录下看到生成的 log ### Nginx 处理跨域请求 @@ -687,3 +1063,4 @@ limit_conn slimits 5; - - - +- \ No newline at end of file diff --git a/Nginx-Keepalived-Install-And-Settings.md b/markdown-file/Nginx-Keepalived-Install-And-Settings.md similarity index 100% rename from Nginx-Keepalived-Install-And-Settings.md rename to markdown-file/Nginx-Keepalived-Install-And-Settings.md diff --git a/Nmon.md b/markdown-file/Nmon.md similarity index 99% rename from Nmon.md rename to markdown-file/Nmon.md index 11493cfe..383711dd 100644 --- a/Nmon.md +++ b/markdown-file/Nmon.md @@ -34,6 +34,7 @@ - 点击 Analyse nmon data 会弹出一个弹出框,选择刚刚转换的 csv 文件,然后就会自动再转化成 excel 文件 - 导出的综合报表的参数说明: + ## 资料 - [Nmon命令行:Linux系统性能的监测利器](http://os.51cto.com/art/201406/442795.htm) diff --git a/Node-Install-And-Usage.md b/markdown-file/Node-Install-And-Usage.md similarity index 74% rename from Node-Install-And-Usage.md rename to markdown-file/Node-Install-And-Usage.md index 3788d5b2..46aa0d6f 100644 --- a/Node-Install-And-Usage.md +++ b/markdown-file/Node-Install-And-Usage.md @@ -21,5 +21,13 @@ curl --silent --location https://rpm.nodesource.com/setup_9.x | sudo bash - sudo yum -y install nodejs ``` +- 验证:`node -v` +- 注意:因为网络原因,最好先把脚本下载到本地,再用代理进行安装 +## nrm 快速切换 NPM 源 + +- 安装:`npm install -g nrm` +- 列表源:`nrm ls` +- 使用源:`nrm use taobao` +- 更多使用方法: diff --git a/Off-line-Yum-Install.md b/markdown-file/Off-line-Yum-Install.md similarity index 100% rename from Off-line-Yum-Install.md rename to markdown-file/Off-line-Yum-Install.md diff --git a/Openfire-Install-And-Settings.md b/markdown-file/Openfire-Install-And-Settings.md similarity index 85% rename from Openfire-Install-And-Settings.md rename to markdown-file/Openfire-Install-And-Settings.md index 88668fe6..527b693c 100644 --- a/Openfire-Install-And-Settings.md +++ b/markdown-file/Openfire-Install-And-Settings.md @@ -61,15 +61,15 @@ - 需要注意的是:在配置数据库 URL 需要特别注意的是需要加入编码设置(你可以按我的这个链接来,但是 IP 和数据库名你自己修改): - `jdbc:mysql://192.168.1.113:3306/openfire?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8` - 如果连接不了数据库,可以看错误日志:`cat /opt/openfire/logs/error.log` -- ![设置](images/Openfire-Settings-a-1.jpg) -- ![设置](images/Openfire-Settings-a-2.jpg) -- ![设置](images/Openfire-Settings-a-3.jpg) -- ![设置](images/Openfire-Settings-a-4.jpg) -- ![设置](images/Openfire-Settings-a-5.jpg) -- ![设置](images/Openfire-Settings-a-6.jpg) -- ![设置](images/Openfire-Settings-a-7.jpg) -- ![设置](images/Openfire-Settings-a-8.jpg) -- ![设置](images/Openfire-Settings-a-9.jpg) +- ![设置](../images/Openfire-Settings-a-1.jpg) +- ![设置](../images/Openfire-Settings-a-2.jpg) +- ![设置](../images/Openfire-Settings-a-3.jpg) +- ![设置](../images/Openfire-Settings-a-4.jpg) +- ![设置](../images/Openfire-Settings-a-5.jpg) +- ![设置](../images/Openfire-Settings-a-6.jpg) +- ![设置](../images/Openfire-Settings-a-7.jpg) +- ![设置](../images/Openfire-Settings-a-8.jpg) +- ![设置](../images/Openfire-Settings-a-9.jpg) ## 使用 Spark 客户端 @@ -80,8 +80,8 @@ - **spark_2_7_7.exe** Offline installation, includes Java JRE (推荐安装这个,即使你有本机已经有了 JDK 环境) - **spark_2_7_7_online.exe** Online installation, does not include Java JRE - 安装完 Spark,启动软件,更玩 QQ 一样道理,具体看下图。你可以用 Spark 登录 Admin 账号。 -- ![设置](images/Openfire-Settings-a-11.jpg) -- ![设置](images/Openfire-Settings-a-12.jpg) +- ![设置](../images/Openfire-Settings-a-11.jpg) +- ![设置](../images/Openfire-Settings-a-12.jpg) - 现在访问 Web 管理界面,给所有在线的会员发个消息,如果你的 Spark 可以收到消息,那就说明整个环境是通的。 -- ![设置](images/Openfire-Settings-a-10.jpg) -- ![设置](images/Openfire-Settings-a-13.jpg) +- ![设置](../images/Openfire-Settings-a-10.jpg) +- ![设置](../images/Openfire-Settings-a-13.jpg) diff --git a/markdown-file/PXC-Install-And-Settings.md b/markdown-file/PXC-Install-And-Settings.md new file mode 100644 index 00000000..37e0db1f --- /dev/null +++ b/markdown-file/PXC-Install-And-Settings.md @@ -0,0 +1,163 @@ +# Percona XtraDB Cluster(PXC)安装和配置 + +## PXC 主要特点 + +- 主要特点:强一致性(比较适合比较注重事务的场景) + - 采用同步复制,事务在所有节点中要嘛是同时提交成功,要嘛不提交,让写入失败 + - 所以,整个集群的写入吞吐量是由最弱的节点限制,如果有一个节点变配置较差,整体质量就是差的 +- 数据同步是双向的,任何节点是从,也是主,都可以进行写入 +- 一般推荐至少 3 个节点 + +## 官网资料 + +- 官网介绍: +- 官网下载: + +## Docker 方式安装 + +- Docker 官方仓库: +- 下载镜像:`docker pull percona/percona-xtradb-cluster` +- 创建需要挂载的目录:`mkdir -p /data/docker/pxc/node1/mysql /data/docker/pxc/node2/mysql /data/docker/pxc/node3/mysql` +- 创建需要挂载的目录:`mkdir -p /data/docker/pxc/node1/backup` +- 赋权:`chmod 777 -R /data/docker/pxc` +- 创建 Docker 网段:`docker network create --subnet=172.18.0.0/24 pxc-net` +- 启动镜像: + +``` +# 初次初始化比较慢,给个 2 分钟左右吧,同时这个节点也用来做全量备份 +docker run -d -p 3307:3306 -v /data/docker/pxc/node1/mysql:/var/lib/mysql -v /data/docker/pxc/node1/backup:/data/backup -e MYSQL_ROOT_PASSWORD=gitnavi123456 -e CLUSTER_NAME=pxc-cluster -e XTRABACKUP_PASSWORD=gitnavi123456 --privileged --name=pxc-node-1 --net=pxc-net --ip 172.18.0.2 percona/percona-xtradb-cluster +``` + +- 使用 SQLyog 测试是否可以连上去,可以才能继续创建其他节点。 + - 连接地址是宿主机 IP,端口是:3307 + +``` +docker run -d -p 3308:3306 -v /data/docker/pxc/node2/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=gitnavi123456 -e CLUSTER_NAME=pxc-cluster -e XTRABACKUP_PASSWORD=gitnavi123456 -e CLUSTER_JOIN=pxc-node-1 --privileged --name=pxc-node-2 --net=pxc-net --ip 172.18.0.3 percona/percona-xtradb-cluster + +docker run -d -p 3309:3306 -v /data/docker/pxc/node3/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=gitnavi123456 -e CLUSTER_NAME=pxc-cluster -e XTRABACKUP_PASSWORD=gitnavi123456 -e CLUSTER_JOIN=pxc-node-1 --privileged --name=pxc-node-3 --net=pxc-net --ip 172.18.0.4 percona/percona-xtradb-cluster +``` + +- 测试集群 + - 用 SQLyog 连上 3 个节点,随便找一个节点创建库,其他几个节点会同时产生库。以此类推,创建表、插入数据,然后查看其他库情况。 + +## 负载均衡 + +- 因为 PXC 是同步是双向的,都支持读写,所以就可以考虑使用负载均衡实现流量分发 +- 使用使用 HAProxy(支持 HTTP 协议、TCP/IP 协议,并且支持虚拟化,可以直接用 Docker 安装) +- 创建需要挂载的目录:`mkdir -p /data/docker/haproxy/conf` +- 赋权:`chmod 777 -R /data/docker/haproxy` +- 创建一个用于 MySQL 心跳检测的用户: + - 连上 PXC 任意一个数据库:`CREATE USER 'haproxy'@'%' IDENTIFIED BY '';` +- 创建配置文件:`vim /data/docker/haproxy/conf/haproxy.cfg` + +``` +global + #工作目录 + chroot /usr/local/etc/haproxy + #日志文件,使用rsyslog服务中local5日志设备(/var/log/local5),等级info + log 127.0.0.1 local5 info + #守护进程运行 + daemon + +defaults + log global + mode http + #日志格式 + option httplog + #日志中不记录负载均衡的心跳检测记录 + option dontlognull + #连接超时(毫秒) + timeout connect 5000 + #客户端超时(毫秒) + timeout client 50000 + #服务器超时(毫秒) + timeout server 50000 + +#监控界面 +listen admin_stats + #监控界面的访问的IP和端口 + bind 0.0.0.0:8118 + #访问协议 + mode http + # URI 相对地址(访问 haproxy 监控地址:http://192.168.0.105:8118/dbs) + stats uri /dbs + #统计报告格式 + stats realm Global\ statistics + #登陆帐户信息(登录名 admin,密码:gitnavi123456) + stats auth admin:gitnavi123456 +#数据库负载均衡 +listen proxy-mysql + #访问的IP和端口 + bind 0.0.0.0:3316 + #网络协议 + mode tcp + #负载均衡算法(轮询算法) + #轮询算法:roundrobin + #权重算法:static-rr + #最少连接算法:leastconn + #请求源IP算法:source + balance roundrobin + #日志格式 + option tcplog + #在 MySQL 中创建一个没有权限的 haproxy 用户,密码为空。Haproxy 使用这个账户对MySQL数据库心跳检测 + option mysql-check user haproxy + #这里填写的端口是 docker 容器的端口,而不是宿主机端口 + server MySQL_1 172.18.0.2:3306 check weight 1 maxconn 2000 + server MySQL_2 172.18.0.3:3306 check weight 1 maxconn 2000 + server MySQL_3 172.18.0.4:3306 check weight 1 maxconn 2000 + #使用keepalive检测死链 + option tcpka +``` + +- 官网 Docker 镜像: +- 运行容器:`docker run -it -d -p 4001:8118 -p 4002:3316 -v /data/docker/haproxy/conf:/usr/local/etc/haproxy --name pxc-haproxy-1 --privileged --net=pxc-net haproxy -f /usr/local/etc/haproxy/haproxy.cfg` +- 浏览器访问: + - 输入:`admin` + - 输入:`gitnavi123456` + - 可以看到 HAProxy 监控界面 +- SQLyog 连接 + - IP:`192.168.0.105` + - 端口:`4002` + - 用户:`root` + - 密码:`gitnavi123456` + - 然后在上面创建对应的数据,如果所有节点都有对应的数据,则表示部署成功 + +## XtraBackup 热备份 + +- XtraBackup 备份过程不锁表 +- XtraBackup 备份过程不会打断正在执行的事务 +- XtraBackup 备份资料经过压缩,磁盘空间占用低 + +#### 全量备份 + +- 容器内安装 XtraBackup,并执行备份语句 + +``` +apt-get update +apt-get install -y percona-xtrabackup-24 + +# 全量备份,备份到 docker 容器的 /data 目录下: +innobackupex --user=root --password=gitnavi123456 /data/backup/full/201806 +``` + +#### 还原全量备份 + + +- PXC 还原数据的时候,必须解散集群,删除掉只剩下一个节点,同时删除节点中的数据 + - 进入容器:`rm -rf /var/lib/mysql/*` +- 回滚备份时没有提交的事务:`innobackupex --user=root --password=gitnavi123456 --apply-back /data/backup/full/2018-04-15_05-09-07/` +- 还原数据:`innobackupex --user=root --password=gitnavi123456 --copy-back /data/backup/full/2018-04-15_05-09-07/` + + +#### 增量备份(未整理) + + +## 资料 + +- +- +- +- +- <> +- <> +- <> diff --git a/markdown-file/Portainer-Install-And-Settings.md b/markdown-file/Portainer-Install-And-Settings.md new file mode 100644 index 00000000..70eef2c8 --- /dev/null +++ b/markdown-file/Portainer-Install-And-Settings.md @@ -0,0 +1,58 @@ +# Portainer 安装和配置、优化 + +## 介绍 + +- 官网: +- 官网 GitHub: +- 官网文档: + +## 安装 + +- 创建文件夹:`mkdir -p /data/docker/portainer` +- 赋权:`chmod -R 777 /data/docker/portainer` +- 创建文件:`vim docker-compose.yml` + +``` +version: '3' +services: + portainer: + container_name: portainer + image: portainer/portainer + volumes: + - /data/docker/portainer:/data + - /var/run/docker.sock:/var/run/docker.sock + ports: + - "9000:9000" +``` + +- 启动:`docker-compose up -d` +- 该容器占用内存非常非常小,只有 5 M 左右。 + +## 对本地监控配置 + +- 因为 Portainer 镜像构建的时候已经配置了:`/var/run/docker.sock:/var/run/docker.sock`,所以对于跟 Portainer 同一台机子的其他容器都可以被直接监控 +- 浏览器访问访问:`http://192.168.1.2:9000` +- 第一次启动会让你创建用户名和密码。第二步就是配置管理哪里的 docker 容器,我这里选择:local + +## 远程监控配置 + +- **以下方法为了方便,没有做任何安全措施,请用于内网** +- 关掉防火墙 +- 修改远程 Docker 配置:`vim /usr/lib/systemd/system/docker.service` + +``` +旧值: +ExecStart=/usr/bin/dockerd + +新值: +ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock +``` + +- 重启 Docker:`systemctl daemon-reload && systemctl reload docker && systemctl restart docker` +- Portainer 启动选择 Remote,填写远程 IP 和端口,比如:`192.168.1.3:2375` + +## 资料 + +- [Portainer 容器管理](https://blog.mallux.me/2017/04/13/portainer/) + + diff --git a/markdown-file/PostgreSQL-Install-And-Settings.md b/markdown-file/PostgreSQL-Install-And-Settings.md new file mode 100644 index 00000000..b2f3182e --- /dev/null +++ b/markdown-file/PostgreSQL-Install-And-Settings.md @@ -0,0 +1,32 @@ +# PostgreSQL 安装和配置 + + +## 官网 + +- 官网: + - 201906 最新版本 + - 12 beat + - 11 release +- 官网 Docker hub: + + +## Docker 安装 PostgreSQL(带挂载) + +``` +docker run \ + -d \ + --name pgsql \ + -p 5432:5432 \ + -e POSTGRES_USER=adg_user \ + -e POSTGRES_PASSWORD=adg123456 \ + -v ~/docker_data/pgsql/data:/var/lib/postgresql/data \ + postgres:11 +``` + +- 连上容器:`docker exec -it pgsql /bin/bash` + - 连上 PostgreSQL:`psql -h 127.0.0.1 -p 5432 -U adg_user` + + +## 资料 + +- diff --git a/markdown-file/Prometheus-Install-And-Settings.md b/markdown-file/Prometheus-Install-And-Settings.md new file mode 100644 index 00000000..7780838c --- /dev/null +++ b/markdown-file/Prometheus-Install-And-Settings.md @@ -0,0 +1,313 @@ +# Prometheus 安装和配置 + +- 不错的发展史说明: +- 特别说明:一般这类环境要尽可能保证所有服务器时间一致 +- Prometheus 本地存储不适合存长久数据,一般存储一个月就够了。要永久存储需要用到远端存储,远端存储可以用 OpenTSDB +- Prometheus 也不适合做日志存储,日志存储还是推荐 ELK 方案 + +## Prometheus Docker 安装 + +- 官网: +- Docker 官方镜像: +- 这里以 Spring Boot Metrics 为收集信息 +- 创建配置文件:`vim /data/docker/prometheus/config/prometheus.yml` +- 在 scrape_configs 位置下增加我们自己应用的路径信息 + +``` +# my global config +global: + scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. + evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. + # scrape_timeout is set to the global default (10s). + +# Alertmanager configuration +alerting: + alertmanagers: + - static_configs: + - targets: + # - alertmanager:9093 + +# Load rules once and periodically evaluate them according to the global 'evaluation_interval'. +rule_files: + # - "first_rules.yml" + # - "second_rules.yml" + +# A scrape configuration containing exactly one endpoint to scrape: +# Here it's Prometheus itself. +scrape_configs: + - job_name: 'springboot' + metrics_path: '/tkey-actuator/actuator/prometheus' + static_configs: + - targets: ['192.168.2.225:8811'] +``` + +- 启动 + +``` +docker run -d --name prometheus -p 9091:9090 \ +-v /data/docker/prometheus/config/prometheus.yml:/etc/prometheus/prometheus.yml \ +prom/prometheus +``` + +- 然后配置 Grafana,使用这个 dashboard: + + +---------------------------------------------------------------------------------------------- + +## 配置 + +- 官网 exporter 列表: +- 官网 exporter 暴露的端口列表: + + +### CentOS7 服务器 + +- 当前最新版本:node_exporter 0.18.1(201907) + +``` +mkdir -p /usr/local/prometheus/node_exporter + +cd /usr/local/prometheus/node_exporter + +wget https://github.com/prometheus/node_exporter/releases/download/v0.18.1/node_exporter-0.18.1.linux-amd64.tar.gz + +tar -zxvf node_exporter-0.18.1.linux-amd64.tar.gz + +``` + + +``` +创建Systemd服务 +vim /etc/systemd/system/node_exporter.service + + + +[Unit] +Description=node_exporter +After=network.target + +[Service] +Type=simple +User=root +ExecStart=/usr/local/prometheus/node_exporter/node_exporter-0.18.1.linux-amd64/node_exporter +Restart=on-failure + +[Install] +WantedBy=multi-user.target +``` + +- 关于 ExecStart 参数,可以再附带一些启动监控的参数,官网介绍: + - 格式:`ExecStart=/usr/local/prometheus/node_exporter/node_exporter-0.18.1.linux-amd64/node_exporter --collectors.enabled meminfo,hwmon,entropy` + + +``` +启动 Node exporter +systemctl start node_exporter + +systemctl daemon-reload + +systemctl status node_exporter + +``` + + +``` +修改prometheus.yml,加入下面的监控目标: + +vim /data/docker/prometheus/config/prometheus.yml + +scrape_configs: + - job_name: 'centos7' + static_configs: + - targets: ['192.168.1.3:9100'] + labels: + instance: centos7_node1 + +``` + +- 重启 prometheus:`docker restart prometheus` +- Grafana 有现成的 dashboard: + - + - + +---------------------------------------------------------------------------------------------- + + +### Nginx 指标 + +- 这里使用 Nginx VTS exporter: + +- 安装 nginx 模块: + +``` +git clone --depth=1 https://github.com/vozlt/nginx-module-vts.git + + +编译 nginx 的时候加上: +./configure --prefix=/usr/local/nginx --with-http_ssl_module --add-module=/opt/nginx-module-vts + +make(已经安装过了,就不要再 make install) +``` + + +``` +也有人做好了 docker 镜像: +https://hub.docker.com/r/xcgd/nginx-vts + +docker run --name nginx-vts -p 80:80 -v /data/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro -d xcgd/nginx-vts +``` + + +``` +修改Nginx配置 + + +http { + vhost_traffic_status_zone; + vhost_traffic_status_filter_by_host on; + + ... + + server { + + ... + + location /status { + vhost_traffic_status_display; + vhost_traffic_status_display_format html; + } + } +} + + +验证nginx-module-vts模块:http://192.168.1.3/status,会展示: +Nginx Vhost Traffic Status 统计表 + +``` + +``` +如果不想统计流量的server,可以禁用vhost_traffic_status,配置示例: +server { + ... + vhost_traffic_status off; + ... +} +``` + + +- 安装 nginx-vts-exporter + +``` +官网版本:https://github.com/hnlq715/nginx-vts-exporter/releases + +wget https://github.com/hnlq715/nginx-vts-exporter/releases/download/v0.10.3/nginx-vts-exporter-0.10.3.linux-amd64.tar.gz + +tar zxvf nginx-vts-exporter-0.10.3.linux-amd64.tar.gz + +chmod +x /usr/local/nginx-vts-exporter-0.10.3.linux-amd64/nginx-vts-exporter +``` + +``` +创建Systemd服务 +vim /etc/systemd/system/nginx_vts_exporter.service + + +[Unit] +Description=nginx_exporter +After=network.target + +[Service] +Type=simple +User=root +ExecStart=/usr/local/nginx-vts-exporter-0.10.3.linux-amd64/nginx-vts-exporter -nginx.scrape_uri=http://192.168.1.3/status/format/json +Restart=on-failure + +[Install] +WantedBy=multi-user.target +``` + + +``` +启动nginx-vts-exporter +systemctl start nginx_vts_exporter.service +systemctl daemon-reload +systemctl status nginx_vts_exporter.service +``` + + +``` +修改 prometheus.yml,加入下面的监控目标: +vim /data/docker/prometheus/config/prometheus.yml + +scrape_configs: + - job_name: 'nginx' + static_configs: + - targets: ['192.168.1.3:9913'] + labels: + instance: nginx1 + + +如果nginx 有加 basic auth,则需要这样: +scrape_configs: + - job_name: "nginx" + metrics_path: /status/format/prometheus + basic_auth: + username: youmeek + password: '123456' + static_configs: + - targets: ['192.168.1.3:9913'] + labels: + instance: 'nginx1' + +``` + +- 重启 prometheus:`docker restart prometheus` +- Grafana 有现成的 dashboard: + - + - + +---------------------------------------------------------------------------------------------- + + + +### 微服务下的多服务收集 + +- + +---------------------------------------------------------------------------------------------- + + +### 告警 + +- +- + +- 告警配置 + +- 告警检测 + +- [Grafana+Prometheus系统监控之邮件报警功能](https://blog.52itstyle.vip/archives/2014/) +- [Grafana+Prometheus系统监控之钉钉报警功能](https://blog.52itstyle.vip/archives/2029/) +- [Grafana+Prometheus系统监控之webhook](https://blog.52itstyle.vip/archives/2068/) + + +## 远端存储方案 + +- + + +---------------------------------------------------------------------------------------------- + + +## 其他资料 + +- + - 写得非常非常非常好 +- +- +- <> +- <> +- <> +- <> +- <> + diff --git a/markdown-file/Python-Ubuntu.md b/markdown-file/Python-Ubuntu.md new file mode 100644 index 00000000..c7b8161b --- /dev/null +++ b/markdown-file/Python-Ubuntu.md @@ -0,0 +1,18 @@ +# Python Ubuntu 安装 + +## 为 Python 开发环境准备 + +#### 给 root 用户安装 Python + +- 切换用户:`sudo su -` +- 安装 Python 2:`apt-get install python` +- 安装 Python 3:`apt-get install python3` +- 查看版本: + - `python --version` + - `python3 --version` + +#### 给非 root 用户安装 Anaconda(Python 3 版本) + +- 官网下载: +- 进入命令行交互安装:`sh Anaconda3-5.2.0-Linux-x86_64.sh` + diff --git a/markdown-file/RabbitMQ-Install-And-Settings.md b/markdown-file/RabbitMQ-Install-And-Settings.md new file mode 100644 index 00000000..b3a84a9a --- /dev/null +++ b/markdown-file/RabbitMQ-Install-And-Settings.md @@ -0,0 +1,164 @@ +# RabbitMQ 安装和配置 + + +## Docker 安装 RabbitMQ + +- 官网镜像: +- 官网镜像说明: +- 一般情况,运行: + +``` +docker run -d --name cloud-rabbitmq -p 5671:5671 -p 5672:5672 -p 4369:4369 -p 25672:25672 -p 15671:15671 -p 15672:15672 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=adg123456 rabbitmq:3-management +``` + +- 带有 websocket stomp 功能(不知道是什么就不用管它): + +``` +docker run -d --name cloud-rabbitmq -p 5671:5671 -p 5672:5672 -p 4369:4369 -p 25672:25672 -p 15671:15671 -p 15672:15672 -p 61613:61613 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=adg123456 rabbitmq:3-management + + +进入 Docker 容器启动 stomp 插件: +docker exec -it cloud-rabbitmq /bin/bash +cd /plugins +rabbitmq-plugins enable rabbitmq_web_stomp +``` + + +- 参数解释: +- rabbitmq:3-management:只有带 management 后缀的才有 web 端管理入口 +- 15672:表示 RabbitMQ 控制台端口号,可以在浏览器中通过控制台来执行 RabbitMQ 的相关操作。容器启动成功后,可以在浏览器输入地址:http://ip:15672/ 访问控制台 +- 5672: 表示 RabbitMQ 所监听的 TCP 端口号,应用程序可通过该端口与 RabbitMQ 建立 TCP 连接,完成后续的异步消息通信 +- RABBITMQ_DEFAULT_USER:用于设置登陆控制台的用户名,这里我设置 admin +- RABBITMQ_DEFAULT_PASS:用于设置登陆控制台的密码,这里我设置 admin + +## RabbitMQ 说明 + +- MQ 全称为 Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。 + - RabbitMQ 是一个在 AMQP 基础上完整的,可复用的企业消息系统。他遵循 Mozilla Public License 开源协议。 +- RabbitMQ WIKI: +- RabbitMQ 百科: +- RabbitMQ 官网: +- RabbitMQ 官网下载: +- RabbitMQ 官网安装文档: +- RabbitMQ 文档: + - 优先: + - 次要: + +## 基于 epel 源进行安装(优先) + +- 来源: + +``` +rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm + +# 安装依赖环境erlang +yum install erlang -y + +# 安装rabbitmq +yum install rabbitmq-server -y +``` + +## 本地安装 + +#### 本地安装 Erlang + +- 有 EPEL 源的情况(需要安装的内容较多,宽带要能跟上):`sudo yum install erlang` +- RabbitMQ 官网提供 Erlang 安装包: + - 下载地址: + - 下载好之后,安装下面两个文件: + - `sudo yum localinstall -y esl-erlang_18.1-1~centos~6_amd64.rpm` + - `sudo yum localinstall -y esl-erlang-compat-18.1-1.noarch.rpm` + + +#### rpm 安装 RabbitMQ + +- 此时(2016-04),最新版:**3.6.1** +- 安装:`rpm --import https://www.rabbitmq.com/rabbitmq-signing-key-public.asc` +- 安装:`sudo yum install -y rabbitmq-server-3.6.1-1.noarch.rpm` +- 启动服务: + - 先看下自己的主机名:`hostname`,我的主机名是:**judasnHost2** + - 先修改一下 host 文件:`vim /etc/hosts`,添加一行:`127.0.0.1 judasnHost2`(必须这样做) + - 启动:`service rabbitmq-server start`,启动一般都比较慢,所以别急 + - 停止:`service rabbitmq-server stop` + - 重启:`service rabbitmq-server restart` + - 设置开机启动:`chkconfig rabbitmq-server on` + + +## 配置 + +- 查找默认配置位置:`find / -name "rabbitmq.config.example"`,我这边搜索结果是:`/usr/share/doc/rabbitmq-server-3.6.1/rabbitmq.config.example` +- 复制默认配置:`cp /usr/share/doc/rabbitmq-server-3.6.1/rabbitmq.config.example /etc/rabbitmq/` +- 修改配置文件名:`cd /etc/rabbitmq ; mv rabbitmq.config.example rabbitmq.config` +- 编辑配置文件,开启用户远程访问:`vim rabbitmq.config` + - 在 64 行,默认有这样一句话:`%% {loopback_users, []},`,注意,该语句最后有一个逗号,等下是要去掉的 + - 我们需要改为:`{loopback_users, []}`, +- 开启 Web 界面管理:`rabbitmq-plugins enable rabbitmq_management` + - 如果你是用 epel 安装的话,则是这样运行:`cd /usr/lib/rabbitmq/bin;./rabbitmq-plugins enable rabbitmq_management` +- 重启 RabbitMQ 服务:`service rabbitmq-server restart` +- 开放防火墙端口: + - `sudo iptables -I INPUT -p tcp -m tcp --dport 15672 -j ACCEPT` + - `sudo iptables -I INPUT -p tcp -m tcp --dport 5672 -j ACCEPT` + - `sudo service iptables save` + - `sudo service iptables restart` +- 浏览器访问:`http://192.168.1.114:15672` + 默认管理员账号:**guest** + 默认管理员密码:**guest** +- 添加新授权用户(如下图所示): + - ![RabbitMQ-Add-User](../images/RabbitMQ-Add-User-a-1.jpg) +- 添加 Host(如下图所示): + - ![RabbitMQ-Add-User](../images/RabbitMQ-Add-User-a-2.jpg) +- 给添加的 Host 设置权限(如下图所示): + - ![RabbitMQ-Add-User](../images/RabbitMQ-Add-User-a-3.gif) +- 交换机绑定队列(如下图所示): + - ![RabbitMQ-Bindings-Queue](../images/RabbitMQ-Bindings-Queue-a-1.gif) + +## 集群环境(镜像队列) + +- TODO + +## 消息重复 + +- 消息重复无法避免,比如消费端异常重启就有可能,或者 MQ 应用挂了重启之后等场景,任何 MQ 应用没有保证消息不会重复发送。 +- 对于一定要保证幂等性的业务场景,在消费端做好标识。比如在 Redis 或 JVM 缓存中存有上一次消费的记录,业务操作之前下判断。 +- 如果是插入操作类的,也可以考虑用唯一约束的方式来保证插入不会重复等。 + +## 消息丢失 + +- 单节点,纯内存情况下一般有三种情况: + - 生产者提交消息到 MQ,但是网络抖动了,丢了。或是 MQ 拿到之后突然挂了,来不及登记 + - MQ 拿到消息,消费者还没消费,但是 MQ 挂了 + - 消费者拿到消息来不及处理,自己挂了,MQ 认为已经消费成功了。 +- 分别解决办法: + - 把 channel 设置为 confirm 模式 + - 持久化队列:创建 queue 的时候持久化 durable=true。持久化消息:生产者发送消息时候:deliveryMode = 2 + - 手动 ACK + +## 消息顺序 + +- 一般场景不需要消息顺序,要去做一般也开销很大,需要执行考虑。 +- 在能保证消息顺序的情况下,可以用来做数据同步 +- 解决: + - 消费者只有单个应用,并且内容不要使用异步或者多线程。在这种场景下绑定 queue,**基于消息队列本质是队列,消息是 FIFO(先进先出)的**,这样消息就能按顺序。但是缺点很明显:吞吐太差,效率太低,适合低效率的业务。 + - 基于上面方案并且对队列进行分片。假设我们原来 repay.queue下面有 10 个消费者线程,那么我们可以创建10个队列,每个队列下面只允许有一个消费者。一个比较简单的方式是,队列命名为 repay.queue-0,repay.queue-2…repay.queue-9,然后生产者推送信息的时候,基于用户的ID(Long类型)mod 10 取模 0…9(取余),再选择发送到相应的队列即可,这样就等保证同一个用户的顺序。 + +## 消息积压 + +- 如果消费者挂掉,消息会一直积压在 MQ 中 +- 解决办法 + - 如果原来有 3 个消费者应用,现在需要准备多倍的消费者应用,假设现在有 10 个新的消费者应用。 + - 创建一个临时的 topic,假设叫做 topic_abc + - 新的 10 个消费者应用绑定在新的 topic_abc 上 + - 修改原来 3 个消费者应用代码,改为接受到 MQ 消息后不操作入数据库了,而是直接发给 topic_abc + - 这样原来积压的消息就有 10 个消费者一起来分摊 + - 如果此时这个 MQ 扛不住压力,那只能让旧的 3 个消费者应用写到其他 MQ,然后 10 个新消费者消费新的 MQ。 + - 然后深夜找个时间重新欢迎旧的 3 个消费者代码。 + + +## 资料 + +- + + + + + diff --git a/Rap-Install-And-Settings.md b/markdown-file/Rap-Install-And-Settings.md similarity index 100% rename from Rap-Install-And-Settings.md rename to markdown-file/Rap-Install-And-Settings.md diff --git a/Redis-Install-And-Settings.md b/markdown-file/Redis-Install-And-Settings.md similarity index 54% rename from Redis-Install-And-Settings.md rename to markdown-file/Redis-Install-And-Settings.md index 4829c354..4278efae 100644 --- a/Redis-Install-And-Settings.md +++ b/markdown-file/Redis-Install-And-Settings.md @@ -1,7 +1,7 @@ ## Redis 安装和配置 -## 如果你用 Spring Data MongoDB 依赖请注意 +## 如果你用 Spring Data Redis 依赖请注意 - 请先看官网最新支持到哪个版本的依赖: - 查看锚点为:`New in Spring Data Redis` 的内容 @@ -14,18 +14,24 @@ ## Docker 下安装 Redis -- 创建一个宿主机目录用来存放 redis 配置文件:`mkdir -p /opt/conf/redis` -- 创建一个宿主机以后用来存放数据的目录:`mkdir -p /data/redis/db` -- 安装镜像:`docker pull redis:3.2` -- 查看下载下来的镜像:`docker images` -- 自己编写一个配置文件 `vim /opt/conf/redis/redis.conf`,内容如下: +- 创建一个宿主机目录用来存放 redis 配置文件:`mkdir -p /data/docker/redis/conf` +- 创建一个宿主机以后用来存放数据的目录:`mkdir -p /data/docker/redis/db` +- 赋权:`chmod 777 -R /data/docker/redis` +- 自己编写一个配置文件 `vim /data/docker/redis/conf/redis.conf`,内容如下: - Redis 默认的配置文件内容: ``` ini -bind 0.0.0.0 -requirepass casredis123456 +安全情况的几个特殊配置: +bind 127.0.0.1 +requirepass adgredis123456 protected-mode yes + +免密情况: +bind 0.0.0.0 +protected-mode no + +其他: port 6379 tcp-backlog 511 timeout 0 @@ -78,13 +84,170 @@ hz 10 aof-rewrite-incremental-fsync yes ``` -- 启动镜像:`docker run -d -ti -p 6379:6379 -v /opt/conf/redis/redis.conf:/etc/redis/redis.conf -v /data/redis/db:/data --restart always --name cas-redis redis:3.2 redis-server /etc/redis/redis.conf` +- 启动镜像:`docker run -d -ti -p 6379:6379 -v /data/docker/redis/conf/redis.conf:/etc/redis/redis.conf -v /data/docker/redis/db:/data --restart always --name cloud-redis redis:3.2 redis-server /etc/redis/redis.conf` - 查看镜像运行情况:`docker ps` -- 进入镜像中 redis shell 交互界面:`docker exec -it 0cdc76fef7b4 redis-cli -h 127.0.0.1 -p 6379 -a casredis123456` -- 重新启动服务:`docker restart cas-redis` +- 进入镜像中 redis shell 交互界面:`docker exec -it cloud-redis redis-cli -h 127.0.0.1 -p 6379 -a adgredis123456` +- 重新启动服务:`docker restart cloud-redis` + + +## RedisCluster 集群(Docker 方式) + +#### Redis 容器准备 + +- 目标:3 主 3 从(一般都是推荐奇数个 master) +- 最小集群数推荐是:3 +- 测试机的最低配置推荐是:2C4G +- 拉取镜像:`docker pull registry.cn-shenzhen.aliyuncs.com/youmeek/redis-to-cluster:3.2.3` +- 重新打个 tag(旧名字太长了):`docker tag registry.cn-shenzhen.aliyuncs.com/youmeek/redis-to-cluster:3.2.3 redis-to-cluster:3.2.3` +- 创建网段:`docker network create --subnet=172.19.0.0/16 net-redis-to-cluster` +- 宿主机创建配置文件:`mkdir -p /data/docker/redis-to-cluster/config && vim /data/docker/redis-to-cluster/config/redis.conf` + +``` +bind 0.0.0.0 +protected-mode yes +port 6379 +tcp-backlog 511 +timeout 0 +tcp-keepalive 300 +daemonize yes +supervised no +pidfile /var/run/redis_6379.pid +loglevel notice +logfile "" +databases 16 +save 900 1 +save 300 10 +save 60 10000 +stop-writes-on-bgsave-error yes +rdbcompression yes +rdbchecksum yes +dbfilename dump.rdb +dir ./ +slave-serve-stale-data yes +slave-read-only yes +repl-diskless-sync no +repl-diskless-sync-delay 5 +repl-disable-tcp-nodelay no +slave-priority 100 +appendonly yes +appendfilename "appendonly.aof" +appendfsync everysec +no-appendfsync-on-rewrite no +auto-aof-rewrite-percentage 100 +auto-aof-rewrite-min-size 64mb +aof-load-truncated yes +lua-time-limit 5000 +cluster-enabled yes +cluster-config-file nodes-6379.conf +cluster-node-timeout 15000 +slowlog-log-slower-than 10000 +slowlog-max-len 128 +latency-monitor-threshold 0 +notify-keyspace-events "" +hash-max-ziplist-entries 512 +hash-max-ziplist-value 64 +list-max-ziplist-size -2 +list-compress-depth 0 +set-max-intset-entries 512 +zset-max-ziplist-entries 128 +zset-max-ziplist-value 64 +hll-sparse-max-bytes 3000 +activerehashing yes +client-output-buffer-limit normal 0 0 0 +client-output-buffer-limit slave 256mb 64mb 60 +client-output-buffer-limit pubsub 32mb 8mb 60 +hz 10 +aof-rewrite-incremental-fsync yes +``` +- 赋权:`chmod 777 -R /data/docker/redis-to-cluster/` +- 运行 6 个节点: + - `docker run -it -d --name redis-to-cluster-1 -p 5001:6379 -v /data/docker/redis-to-cluster/config/redis.conf:/usr/redis/redis.conf --net=net-redis-to-cluster --ip 172.19.0.2 redis-to-cluster:3.2.3 bash` + - `docker run -it -d --name redis-to-cluster-2 -p 5002:6379 -v /data/docker/redis-to-cluster/config/redis.conf:/usr/redis/redis.conf --net=net-redis-to-cluster --ip 172.19.0.3 redis-to-cluster:3.2.3 bash` + - `docker run -it -d --name redis-to-cluster-3 -p 5003:6379 -v /data/docker/redis-to-cluster/config/redis.conf:/usr/redis/redis.conf --net=net-redis-to-cluster --ip 172.19.0.4 redis-to-cluster:3.2.3 bash` + - `docker run -it -d --name redis-to-cluster-4 -p 5004:6379 -v /data/docker/redis-to-cluster/config/redis.conf:/usr/redis/redis.conf --net=net-redis-to-cluster --ip 172.19.0.5 redis-to-cluster:3.2.3 bash` + - `docker run -it -d --name redis-to-cluster-5 -p 5005:6379 -v /data/docker/redis-to-cluster/config/redis.conf:/usr/redis/redis.conf --net=net-redis-to-cluster --ip 172.19.0.6 redis-to-cluster:3.2.3 bash` + - `docker run -it -d --name redis-to-cluster-6 -p 5006:6379 -v /data/docker/redis-to-cluster/config/redis.conf:/usr/redis/redis.conf --net=net-redis-to-cluster --ip 172.19.0.7 redis-to-cluster:3.2.3 bash` +- 配置 redis-to-cluster-1 节点:`docker exec -it redis-to-cluster-1 bash` + - 启动容器的 redis:`/usr/redis/src/redis-server /usr/redis/redis.conf` +- 其他 5 个节点一样进行启动。 + +#### 创建 Cluster 集群(通过 redis-trib.rb) + +- 配置 redis-to-cluster-1 节点(或者选择其他任意一个节点):`docker exec -it redis-to-cluster-1 bash` +- `mkdir -p /usr/redis/cluster` +- `cp /usr/redis/src/redis-trib.rb /usr/redis/cluster/` +- `cd /usr/redis/cluster/` +- 创建 Cluster 集群(会有交互)(镜像中已经安装了 ruby 了):`./redis-trib.rb create --replicas 1 172.19.0.2:6379 172.19.0.3:6379 172.19.0.4:6379 172.19.0.5:6379 172.19.0.6:6379 172.19.0.7:6379` + - `--replicas 1` 表示为每个主节点创建一个从节点 + - 如果正常的话,会出现下面内容: -## Redis 安装 +``` +>>> Creating cluster +>>> Performing hash slots allocation on 6 nodes... +Using 3 masters: +172.19.0.2:6379 +172.19.0.3:6379 +172.19.0.4:6379 +Adding replica 172.19.0.5:6379 to 172.19.0.2:6379 +Adding replica 172.19.0.6:6379 to 172.19.0.3:6379 +Adding replica 172.19.0.7:6379 to 172.19.0.4:6379 +M: 9c1c64b18bfc2a0586be2089f13c330787c1f67b 172.19.0.2:6379 + slots:0-5460 (5461 slots) master +M: 35a633853329c9ff25bb93a7ce9192699c2ab6a8 172.19.0.3:6379 + slots:5461-10922 (5462 slots) master +M: 8ea2bfeeeda939abb43e96a95a990bcc55c10389 172.19.0.4:6379 + slots:10923-16383 (5461 slots) master +S: 9cb00acba065120ea96834f4352c72bb50aa37ac 172.19.0.5:6379 + replicates 9c1c64b18bfc2a0586be2089f13c330787c1f67b +S: 8e2a4bb11e97adf28427091a621dbbed66c61001 172.19.0.6:6379 + replicates 35a633853329c9ff25bb93a7ce9192699c2ab6a8 +S: 5d0fe968559af3035d8d64ab598f2841e5f3a059 172.19.0.7:6379 + replicates 8ea2bfeeeda939abb43e96a95a990bcc55c10389 +Can I set the above configuration? (type 'yes' to accept): yes +>>> Nodes configuration updated +>>> Assign a different config epoch to each node +>>> Sending CLUSTER MEET messages to join the cluster +Waiting for the cluster to join...... +>>> Performing Cluster Check (using node 172.19.0.2:6379) +M: 9c1c64b18bfc2a0586be2089f13c330787c1f67b 172.19.0.2:6379 + slots:0-5460 (5461 slots) master +M: 35a633853329c9ff25bb93a7ce9192699c2ab6a8 172.19.0.3:6379 + slots:5461-10922 (5462 slots) master +M: 8ea2bfeeeda939abb43e96a95a990bcc55c10389 172.19.0.4:6379 + slots:10923-16383 (5461 slots) master +M: 9cb00acba065120ea96834f4352c72bb50aa37ac 172.19.0.5:6379 + slots: (0 slots) master + replicates 9c1c64b18bfc2a0586be2089f13c330787c1f67b +M: 8e2a4bb11e97adf28427091a621dbbed66c61001 172.19.0.6:6379 + slots: (0 slots) master + replicates 35a633853329c9ff25bb93a7ce9192699c2ab6a8 +M: 5d0fe968559af3035d8d64ab598f2841e5f3a059 172.19.0.7:6379 + slots: (0 slots) master + replicates 8ea2bfeeeda939abb43e96a95a990bcc55c10389 +[OK] All nodes agree about slots configuration. +>>> Check for open slots... +>>> Check slots coverage... +[OK] All 16384 slots covered. +``` + +- 连接集群测试: + - 进入随便一个节点:`docker exec -it redis-to-cluster-1 bash` + - `/usr/redis/src/redis-cli -c` + - 查看集群情况:`cluster nodes` + - 写入数据:`set myKey myValue`,如果成功会返回:`Redirected to slot [16281] located at 172.19.0.4:6379`,可以推断它是 redis-to-cluster-3 容器 + - 暂定掉 redis-to-cluster-3 容器:`docker pause redis-to-cluster-3` + - 重新连接:`/usr/redis/src/redis-cli -c` + - 查看集群情况:`cluster nodes` + - 获取值:`get myKey` + - 重新启动 redis-to-cluster-3:`docker unpause redis-to-cluster-3` + - 查看集群情况:`cluster nodes` +- Spring Boot 项目 Docker 容器访问 RedisCluster + - application.yml 配置的 IP 地址:172.19.0.2 等 + - docker 容器启动增加 `--net=host` 使用宿主机网络 + + +## Redis 编译安装 - Redis 安装 - 官网: @@ -92,22 +255,20 @@ aof-rewrite-incremental-fsync yes - 官网 Github 地址: - 此时(20160212) Redis 最新稳定版本为:**3.0.7** - 官网帮助中心: - - 我个人习惯 `/opt` 目录下创建一个目录 `setups` 用来存放各种软件安装包;在 `/usr` 目录下创建一个 `program` 用来存放各种解压后的软件包,下面的讲解也都是基于此习惯 - - 我个人已经使用了第三方源:`EPEL、RepoForge`,如果你出现 `yum install XXXXX` 安装不成功的话,很有可能就是你没有相关源,请查看我对源设置的文章 - - Redis 下载:`wget http://download.redis.io/releases/redis-3.0.7.tar.gz` (大小:1.4 M) + - Redis 下载(/usr/local):`wget http://download.redis.io/releases/redis-3.0.7.tar.gz` (大小:1.4 M) - 安装依赖包:`yum install -y gcc-c++ tcl` - 解压:`tar zxvf redis-3.0.7.tar.gz` - - 移动到我个人安装目录:`mv redis-3.0.7/ /usr/program/` - - 进入解压后目录:`cd /usr/program/redis-3.0.7/` + - 进入解压后目录:`cd /usr/local/redis-3.0.7/` - 编译:`make` - 编译安装:`make install` - 安装完之后会在:`/usr/local/bin` 目录下生成好几个 redis 相关的文件 - - 复制配置文件:`cp /usr/program/redis-3.0.7/redis.conf /etc/` + - 复制配置文件:`cp /usr/local/redis-3.0.7/redis.conf /etc/` - 修改配置:`vim /etc/redis.conf` - 把旧值:`daemonize no` - 改为新值:`daemonize yes` - 启动:`/usr/local/bin/redis-server /etc/redis.conf` - 关闭:`redis-cli -h 127.0.0.1 -p 6379 shutdown` + - 关闭(带密码):`redis-cli -h 127.0.0.1 -p 6379 -a 123456 shutdown` - 查看是否启动:`ps -ef | grep redis` - 进入客户端:`redis-cli` - 关闭客户端:`redis-cli shutdown` @@ -259,6 +420,7 @@ aof-rewrite-incremental-fsync yes - 官网命令列表: - `SET key value`,设值。eg:`SET myblog www.youmeek.com` - `GET key`,取值 +- `SELECT 0`,切换数据库 - `INCR key`,递增数字 - `DECR key`,递减数字 - `KEYS *`,查看当前数据库下所有的 key @@ -389,7 +551,7 @@ esac - 官网: - 官网下载: - 效果如下图: - - ![Redis Desktop Manager](images/Redis-GUI-a-1.jpg) + - ![Redis Desktop Manager](../images/Redis-GUI-a-1.jpg) @@ -453,6 +615,88 @@ esac - 配置文件也跟原版本不一样,叫做:`redis.windows.conf` +## Redis Info + +- 客户端下命令行:`info` + - 参考: + +``` +server 部分记录了 Redis 服务器的信息,它包含以下域: + +redis_version : Redis 服务器版本 +redis_git_sha1 : Git SHA1 +redis_git_dirty : Git dirty flag +os : Redis 服务器的宿主操作系统 +arch_bits : 架构(32 或 64 位) +multiplexing_api : Redis 所使用的事件处理机制 +gcc_version : 编译 Redis 时所使用的 GCC 版本 +process_id : 服务器进程的 PID +run_id : Redis 服务器的随机标识符(用于 Sentinel 和集群) +tcp_port : TCP/IP 监听端口 +uptime_in_seconds : 自 Redis 服务器启动以来,经过的秒数 +uptime_in_days : 自 Redis 服务器启动以来,经过的天数 +lru_clock : 以分钟为单位进行自增的时钟,用于 LRU 管理 +clients 部分记录了已连接客户端的信息,它包含以下域: + +connected_clients : 已连接客户端的数量(不包括通过从属服务器连接的客户端) +client_longest_output_list : 当前连接的客户端当中,最长的输出列表 +client_longest_input_buf : 当前连接的客户端当中,最大输入缓存 +blocked_clients : 正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量 +memory 部分记录了服务器的内存信息,它包含以下域: + +used_memory : 由 Redis 分配器分配的内存总量,以字节(byte)为单位 +used_memory_human : 以人类可读的格式返回 Redis 分配的内存总量 +used_memory_rss : 从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致。 +used_memory_peak : Redis 的内存消耗峰值(以字节为单位) +used_memory_peak_human : 以人类可读的格式返回 Redis 的内存消耗峰值 +used_memory_lua : Lua 引擎所使用的内存大小(以字节为单位) +mem_fragmentation_ratio : used_memory_rss 和 used_memory 之间的比率 +mem_allocator : 在编译时指定的, Redis 所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc 。 +``` + +- 常关注信息: + +``` +used_memory_rss_human:系统给redis分配的内存(即常驻内存) +used_memory_peak_human : Redis 的内存消耗峰值 +used_memory_lua_human : 系统内存大小 +expired_keys : 过期的的键数量 +evicted_keys : 因为最大内存容量限制而被驱逐(evict)的键数量 +used_cpu_sys_children : Redis 后台进程在 内核态 消耗的 CPU +used_cpu_user_children : Redis 后台进程在 用户态 消耗的 CPU +``` + +## Redis 基准压力测试 + +- 默认安装包下就自带 +- 官网文档: +- 运行:`redis-benchmark -q -n 100000` + - `-q` 表示 quiet 安静执行,结束后直接输出结果即可 + - `-n 100000` 请求 10 万次 + +``` +PING_INLINE: 62189.05 requests per second +PING_BULK: 68634.18 requests per second +SET: 58241.12 requests per second +GET: 65445.03 requests per second +INCR: 57703.40 requests per second +LPUSH: 61199.51 requests per second +RPUSH: 68119.89 requests per second +LPOP: 58309.04 requests per second +RPOP: 63775.51 requests per second +SADD: 58479.53 requests per second +HSET: 61500.61 requests per second +SPOP: 58241.12 requests per second +LPUSH (needed to benchmark LRANGE): 59523.81 requests per second +LRANGE_100 (first 100 elements): 60350.03 requests per second +LRANGE_300 (first 300 elements): 57636.89 requests per second +LRANGE_500 (first 450 elements): 63251.11 requests per second +LRANGE_600 (first 600 elements): 58479.53 requests per second +MSET (10 keys): 56401.58 requests per second +``` + +- 只测试特定类型:`redis-benchmark -t set,lpush -n 100000 -q` + ## 资料 diff --git a/markdown-file/SSH-login-without-password.md b/markdown-file/SSH-login-without-password.md new file mode 100644 index 00000000..b13e35cd --- /dev/null +++ b/markdown-file/SSH-login-without-password.md @@ -0,0 +1,41 @@ +# SSH 免密登录 + +## 环境说明 + +- CentOS 7.3 + +## 关键点 + +- 免密登录的关键点在于理解谁登录谁。 +- A 生成的公钥给 B,也给 C、D,则 A 可以直接免密 SSH 登录 B、C、D + +## A 生成密钥 + +- 在 A 机器上输入命令:`ssh-keygen` + - 根据提示回车,共有三次交互提示,都回车即可。 +- 生成的密钥目录在:**/root/.ssh** +- 写入:`cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys` +- 测试:`ssh localhost` + + +## 把 A 的公钥发给 B + +- 假设 B 机器的 ip:`192.168.1.105` +- 则在 A 机器上输入:`ssh-copy-id -i /root/.ssh/id_rsa.pub -p 22 root@192.168.1.105`,根据提示输入 B 机器的 root 密码,成功会有相应提示 + +## 测试 A 免密登录到 B + +- 在 A 机器上输入命令:`ssh -p 22 root@192.168.1.105`,则会相应登录成功的提示 + +------------------------------------------------------------------- + +## 如果是用 pem 登录的话,用 ssh-copy-id 是无法使用的 + +- 先保存 A 的 pub 到本地:`sz /root/.ssh/id_rsa.pub` +- 登录 B 机子:`cd /root/.ssh/` +- 如果 B 机子没有 authorized_keys 文件则创建:`touch /root/.ssh/authorized_keys` + - 设置权限:`chmod 600 /root/.ssh/authorized_keys ` +- 上传 pub 文件到 B 机子,并在 B 机子上执行:`cd /root/.ssh/ && cat id_rsa.pub >> authorized_keys` + + + diff --git a/markdown-file/SSH.md b/markdown-file/SSH.md new file mode 100644 index 00000000..ecd0b9ca --- /dev/null +++ b/markdown-file/SSH.md @@ -0,0 +1,162 @@ +# SSH(Secure Shell)介绍 + + +## SSH 安装 + +- 查看是否已安装: + - CentOS:`rpm -qa | grep openssh` + - Ubuntu:`dpkg -l | grep openssh` + +- 安装: + - CentOS 6:`sudo yum install -y openssh-server openssh-clients` + - Ubuntu:`sudo apt-get install -y openssh-server openssh-client` + +## 特别注意:本文内容,修改完配置都要记得重启服务 + +- CentOS 6 命令:`service sshd restart` +- CentOS 7 命令:`systemctl restart sshd.service` + +## SSH 修改连接端口 + +- 配置文件介绍(记得先备份):`sudo vim /etc/ssh/sshd_config` +- 打开这一行注释:Port 22 + - 自定义端口选择建议在万位的端口,如:10000-65535之间,假设这里我改为 60001 +- CentOS 6 给新端口加到防火墙中: + - 添加规则:`iptables -I INPUT -p tcp -m tcp --dport 60001 -j ACCEPT` + - 保存规则:`service iptables save` + - 重启 iptables:`service iptables restart` +- CentOS 7:添加端口:`firewall-cmd --zone=public --add-port=60001/tcp --permanent` + - 重启防火墙:`firewall-cmd --reload` + +## 设置超时 + +- ClientAliveInterval指定了服务器端向客户端请求消息的时间间隔, 默认是0,不发送。而ClientAliveInterval 300表示5分钟发送一次,然后客户端响应,这样就保持长连接了。 +- ClientAliveCountMax,默认值3。ClientAliveCountMax表示服务器发出请求后客户端没有响应的次数达到一定值,就自动断开,正常情况下,客户端不会不响应。 +- 正常我们可以设置为: + - ClientAliveInterval 300 + - ClientAliveCountMax 3 + - 按上面的配置的话,300*3=900秒=15分钟,即15分钟客户端不响应时,ssh连接会自动退出。 + +## SSH 允许 root 账户登录 + +- 编辑配置文件(记得先备份):`sudo vim /etc/ssh/sshd_config` + - 允许 root 账号登录 + - 注释掉:`PermitRootLogin without-password` + - 新增一行:`PermitRootLogin yes` + +## SSH 不允许 root 账户登录 + +- 新增用户和把新增的用户改为跟 root 同等权限方法:[Bash.md] +- 编辑配置文件(记得先备份):`sudo vim /etc/ssh/sshd_config` + - 注释掉这一句(如果没有这一句则不管它):`PermitRootLogin yes` + +## SSH 密钥登录 + +- 生成秘钥和公钥文件,命令:`sudo ssh-keygen`,在交互提示中连续按三次回车,如果看得懂交互的表达,那就根据你自己需求来。默认生成密钥和公钥文件是在:/root/.ssh。 +- 进入生成目录:`cd /root/.ssh`,可以看到有两个文件:id_rsa (私钥) 和 id_rsa.pub (公钥) +- 在 .ssh 目录下创建 SSH 认证文件,命令:`touch /root/.ssh/authorized_keys` +- 将公钥内容写到SSH认证文件里面,命令:`cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys` +- 修改SSH认证文件权限,命令: + - `sudo chmod 700 /root/.ssh` + - `sudo chmod 600 /root/.ssh/authorized_keys` +- 重启服务:`sudo service sshd restart` +- 设置 SSH 服务默认启动:`sudo sysv-rc-conf ssh on` +- 现在 SSH 客户端可以去拿着 SSH 服务器端上的 id_rsa,在客户端指定秘钥文件地址即可,这个一般由于你使用的客户端决定的,我这里推荐的是 Xshell 软件。 +- 另外一种方法可以查看:[SSH 免密登录(推荐)](SSH-login-without-password.md) + +## 限制只有某一个IP才能远程登录服务器 + +- 在该配置文件:`vim /etc/hosts.deny` + - 添加该内容:`sshd:ALL` +- 在该配置文件:`vim /etc/hosts.allow` + - 添加该内容:`sshd:123.23.1.23` + +## 限制某些用户可以 SSH 访问 + +- 在该配置文件:`vim /etc/ssh/sshd_config` + - 添加该内容:`AllowUsers root userName1 userName2` + + +## 常用 SSH 连接终端 + +- Windows -- Xshell: +- Mac -- ZOC: + +## 查看 SSH 登录日志 + +#### CentOS 6 + +- 查看登录失败记录:`cat /var/log/auth.log | grep "Failed password"` + - 如果数据太多可以用命令:`tail -500f /var/log/auth.log | grep "Failed password"` +- 统计哪些 IP 尝试多少次失败登录记录:`grep "Failed password" /var/log/auth.log | awk ‘{print $11}’ | uniq -c | sort -nr` +- 统计哪些 IP 尝试多少次失败登录记录,并排序:`grep "Failed password" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -nr | more` + + +#### CentOS 7 + +- 查看登录失败:`egrep "Failed|Failure" /var/log/secure`,可以得到类似信息: + - 如果数据太多,可以用命令:`tail -500f /var/log/secure | egrep "Failed|Failure"` + +``` +Feb 21 16:10:15 U5NHTIHOW67HKAH sshd[32753]: Failed password for invalid user oracle from 1.175.83.6 port 46560 ssh2 +Feb 21 16:10:16 U5NHTIHOW67HKAH sshd[32750]: Failed password for root from 42.7.26.88 port 62468 ssh2 +Feb 21 16:10:17 U5NHTIHOW67HKAH sshd[32744]: Failed password for root from 42.7.26.85 port 36086 ssh2 +Feb 21 16:10:18 U5NHTIHOW67HKAH sshd[32756]: Failed password for invalid user oracle from 1.175.83.6 port 46671 ssh2 +Feb 21 16:10:20 U5NHTIHOW67HKAH sshd[32744]: Failed password for root from 42.7.26.85 port 36086 ssh2 +Feb 21 16:10:21 U5NHTIHOW67HKAH sshd[32750]: Failed password for root from 42.7.26.88 port 62468 ssh2 +Feb 21 16:10:21 U5NHTIHOW67HKAH sshd[32758]: Failed password for invalid user oracle from 1.175.83.6 port 46811 ssh2 +``` + +- 查看登录失败统计:`grep "authentication failure" /var/log/secure`,可以得到类似信息: + - 如果数据太多,可以用命令:`tail -500f /var/log/secure | grep "authentication failure"` + +``` +Feb 21 02:01:46 U5NHTIHOW67HKAH sshd[16854]: Disconnecting: Too many authentication failures for root [preauth] +Feb 21 02:01:46 U5NHTIHOW67HKAH sshd[16854]: PAM 5 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:01:47 U5NHTIHOW67HKAH sshd[16858]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:02:02 U5NHTIHOW67HKAH sshd[16858]: Disconnecting: Too many authentication failures for root [preauth] +Feb 21 02:02:02 U5NHTIHOW67HKAH sshd[16858]: PAM 5 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:03:11 U5NHTIHOW67HKAH sshd[16870]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:03:25 U5NHTIHOW67HKAH sshd[16870]: Disconnecting: Too many authentication failures for root [preauth] +Feb 21 02:03:25 U5NHTIHOW67HKAH sshd[16870]: PAM 5 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:03:29 U5NHTIHOW67HKAH sshd[16872]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:03:44 U5NHTIHOW67HKAH sshd[16872]: Disconnecting: Too many authentication failures for root [preauth] +Feb 21 02:03:44 U5NHTIHOW67HKAH sshd[16872]: PAM 5 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:03:45 U5NHTIHOW67HKAH sshd[16875]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:04:01 U5NHTIHOW67HKAH sshd[16875]: Disconnecting: Too many authentication failures for root [preauth] +Feb 21 02:04:01 U5NHTIHOW67HKAH sshd[16875]: PAM 5 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:04:05 U5NHTIHOW67HKAH sshd[16878]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:04:20 U5NHTIHOW67HKAH sshd[16878]: Disconnecting: Too many authentication failures for root [preauth] +Feb 21 02:04:20 U5NHTIHOW67HKAH sshd[16878]: PAM 5 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:04:24 U5NHTIHOW67HKAH sshd[16883]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:04:40 U5NHTIHOW67HKAH sshd[16883]: Disconnecting: Too many authentication failures for root [preauth] +Feb 21 02:04:40 U5NHTIHOW67HKAH sshd[16883]: PAM 5 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:04:43 U5NHTIHOW67HKAH sshd[16886]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:04:59 U5NHTIHOW67HKAH sshd[16886]: Disconnecting: Too many authentication failures for root [preauth] +Feb 21 02:04:59 U5NHTIHOW67HKAH sshd[16886]: PAM 5 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:05:02 U5NHTIHOW67HKAH sshd[16888]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:05:08 U5NHTIHOW67HKAH sshd[16891]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=146.0.228.146 +Feb 21 02:05:18 U5NHTIHOW67HKAH sshd[16888]: Disconnecting: Too many authentication failures for root [preauth] +Feb 21 02:05:18 U5NHTIHOW67HKAH sshd[16888]: PAM 5 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:05:20 U5NHTIHOW67HKAH sshd[16899]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:05:34 U5NHTIHOW67HKAH sshd[16899]: Disconnecting: Too many authentication failures for root [preauth] +Feb 21 02:05:34 U5NHTIHOW67HKAH sshd[16899]: PAM 5 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:05:37 U5NHTIHOW67HKAH sshd[16901]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=42.7.26.85 user=root +Feb 21 02:05:53 U5NHTIHOW67HKAH sshd[16901]: Disconnecting: Too many authentication failures for root [preauth] +``` + +## 防止 SSH 暴力破解:DenyHosts + +- 官网地址: +- 参考文章: + - + - + - + - + +## SSH 资料 + +- +- +- +- diff --git a/markdown-file/SSR-Client-Ubuntu.md b/markdown-file/SSR-Client-Ubuntu.md new file mode 100644 index 00000000..21028f8c --- /dev/null +++ b/markdown-file/SSR-Client-Ubuntu.md @@ -0,0 +1,91 @@ +# SSR Ubuntu 客户端 + +## 介绍 + +- 因为某些原因,这个东西不做过多解释 + +## 安装 + +- 需要 Git 环境: +- 需要 Python 2 环境: +- 官网脚本: +- 我们这里使用别人提供的文件,如果该文件被屏蔽,就自行用上面官网的文件。 + +``` +wget http://www.djangoz.com/ssr + +sudo mv ssr /usr/local/bin + +sudo chmod 766 /usr/local/bin/ssr + +ssr install +``` + +- 配置:`ssr config` + - 这是一个 vim 的配置界面,也可以直接编辑其源文件: +- 主要修改如下内容: + +``` +"server":"12.26.68.99", //服务器ip +"server_port":9191, //端口 +"password":"123456", //密码 +"protocol":"auth_sha1_v4", //协议插件 +"obfs":"http_simple", //混淆插件 +"method":"aes-256-cfb", //加密方式 +``` + + +- 启动:`ssr start` +- 其他常用命令: + - `ssr stop` + - `ssr help` +- 然后就可以用 Chrome 的 SwitchyOmega +- AutoProxy:https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt + +## 配置终端代理 polipo + +- 安装:`sudo apt-get install polipo` +- 修改配置(一般不要变动,直接复制上去即可):`sudo vim /etc/polipo/config` + +``` +# This file only needs to list configuration variables that deviate +# from the default values. See /usr/share/doc/polipo/examples/config.sample +# and "polipo -v" for variables you can tweak and further information. + +logSyslog = true +logFile = /var/log/polipo/polipo.log + +proxyAddress = "0.0.0.0" + +socksParentProxy = "127.0.0.1:1080" +socksProxyType = socks5 + +chunkHighMark = 50331648 +objectHighMark = 16384 + +serverMaxSlots = 64 +serverSlots = 16 +serverSlots1 = 32 +``` + +- 重启:`sudo service polipo restart` + +#### 开始测试 polipo + +- 获取自己当前 IP:`curl ip.gs` + - 这时候应该是国内 IP + +- **开始使用代理**:`export http_proxy=http://127.0.0.1:8123` + +- 获取自己当前 IP:`curl ip.gs` + - 这时候应该是国外 IP + +- **取消代理**:`unset http_proxy` + +- 获取自己当前 IP:`curl ip.gs` + - 这时候应该是国内 IP +- 另外:在浏览器中输入 便可以进入到 Polipo 的使用说明和配置界面。 + +## 材料 + +- diff --git a/SVN-Install-And-Settings.md b/markdown-file/SVN-Install-And-Settings.md similarity index 96% rename from SVN-Install-And-Settings.md rename to markdown-file/SVN-Install-And-Settings.md index c9fefb9a..01d4795b 100644 --- a/SVN-Install-And-Settings.md +++ b/markdown-file/SVN-Install-And-Settings.md @@ -105,7 +105,7 @@ - 设置配置文件 - 编辑配置文件:`vim /opt/svn/repo/conf/svnserve.conf` - - ![设置配置文件](images/SVN-Install-And-Settings-a-1.jpg) + - ![设置配置文件](../images/SVN-Install-And-Settings-a-1.jpg) - 配置文件中下面几个参数(默认是注释的): - `anon-access`: 对不在授权名单中的用户访问仓库的权限控制,有三个可选性:`write、read、none` - `none` 表示没有任何权限 @@ -123,13 +123,13 @@ - 添加用户 - 编辑配置文件:`vim /opt/svn/repo/conf/passwd` - - ![添加用户](images/SVN-Install-And-Settings-a-2.jpg) + - ![添加用户](../images/SVN-Install-And-Settings-a-2.jpg) - 添加用户很简答,如上图所示在配置文中添加一个格式为:`用户名 = 密码` 的即可 - 设置用户权限 - 编辑配置文件:`vim /opt/svn/repo/conf/authz` - - ![设置用户权限](images/SVN-Install-And-Settings-a-3.jpg) + - ![设置用户权限](../images/SVN-Install-And-Settings-a-3.jpg) - 配置文件中几个参数解释: - `r` 表示可写 - `w` 表示可读 @@ -161,7 +161,7 @@ ## SVN 设置提交之后可修改提交的 Message 信息 - 默认的 SVN 是无法修改提交后的 Message 信息的,修改会报如下错误: -- ![SVN 设置提交之后可修改提交的 Message 信息](images/SVN-Install-And-Settings-a-4.jpg) +- ![SVN 设置提交之后可修改提交的 Message 信息](../images/SVN-Install-And-Settings-a-4.jpg) - 解决办法: - 下载我 hooks 文件: - 把 pre-revprop-change 文件放在你的仓库下,比如我仓库地址是:`/opt/svn/repo/hooks` diff --git a/markdown-file/Samba.md b/markdown-file/Samba.md new file mode 100644 index 00000000..07938583 --- /dev/null +++ b/markdown-file/Samba.md @@ -0,0 +1,137 @@ +# Samba 介绍 + + +## Samba 安装 + +- 查看是否已安装: + - CentOS:`rpm -qa | grep samba` + - Ubuntu:`dpkg -l | grep samba` + +- 安装: + - CentOS 6:`yum install samba samba-client samba-common` + - Ubuntu:`sudo apt-get install -y samba samba-client` + +## Samba 服务器配置文件常用参数 + +- 配置文件介绍(记得先备份 `cp /etc/samba/smb.conf /etc/samba/smb.conf.backup`):`sudo vim /etc/samba/smb.conf` + - 该配置解释: + - 在 [global] 区域 + - workgroup = WORKGROUP #WORKGROUP表示Windows默认的工作组名称,一般共享给windows是设置为WORKGROUP,此字段不重要,无需与 Windows 的域保持一致 + - security = user #ubuntu下配置文件默认没有这句,这个是自己填上去的。表示指定samba的安全等级,安全等级分别有四种:share(其他人不需要账号密码即可访问共享目录)、user(检查账号密码)、server(表示检查密码由另外一台服务器负责)、domain(指定Windows域控制服务器来验证用户的账号和密码) + 注: samba 4 不再支持 security = share (查看版本 smbd --version) + - 在新区域区域 + - 当 security = share 使用下面这段,这段自己添加的,其中myshare这个名字表示其他机子访问该分享地址时用:file://该服务机IP/myshare + ``` + [myshare] + comment = share all + path = /opt/mysamba #分享的目录,其中这个目录需要chmod 777 /opt/mysamba权限 + browseable = yes + writable = yes + public =yes + ``` + - 当 security = user 使用下面这段,这段自己添加的,其中 myshare2 这个名字表示其他机子访问该分享地址时用:file://该服务机IP/myshare2 + - 可以返回的账号必须是系统已经存在的账号。先给系统添加账号:`useradd user1`,再用samba的设置添加账号:`pdbedit -a user1`,会让你设立该samba账号密码。列出账号:`pdbedit -L` + ``` + [myshare2] + comment = share for users + path = /opt/mysamba2 #分享的目录,其中这个目录需要chmod 777 /opt/mysamba权限 + # (不一定要 777 权限,只要登录 samba 的用户是这个目录的用户即可,那么在 Windows 中的文件创建和写入都等同于 linux 的等价账户) + browseable = yes + writable = yes + public = no + read only = no + guest ok = no # samba 4 拥有的 + create mask = 0646 + force create mode = 0646 + directory mask = 0747 + force directory mode = 0747 + ``` + + - 一份成功的 samba 4 配置 + ``` + [global] + workgroup = WORKGROUP + passdb backend = tdbsam + printing = cups + printcap name = cups + printcap cache time = 750 + cups options = raw + map to guest = Bad User + include = /etc/samba/dhcp.conf + logon path = \\%L\profiles\.msprofile + logon home = \\%L\%U\.9xprofile + logon drive = P: + max connections = 0 + deadtime = 0 + max log size = 500 +[share1] + path = /home/ + browsable =yes + writable = yes + read only = no + guest ok=no + create mask = 0646 + force create mode = 0646 + directory mask = 0747 + force directory mode = 0747 + ``` +- 启动服务(CentOS 6): + - `sudo service samba restart` + - `service smb restart` # 启动 samba +- 启动服务(CentOS 7): + - `systemctl start smb.service` # 启动 samba + - `systemctl enable smb.service` # 激活 + - `systemctl status smb.service` # 查询 samba 状态(启动 samba 前后可以用查询验证) +- 启动服务(Ubuntu 16.04.3 -- ljoaquin提供): + - `sudo service smbd restart` + + +## Samba 登录及验证 + +- 在 Windows 连接 Samba 之前,可在本地(linux)使用命令验证 + + `smbclient –L //localhost/ -U ` + 接下来输入的 password 来自于 `pdbedit -a user1` 命令为该用户设置的密码,不一定是 linux 用户密码 + 来自 `/etc/samba/smb.conf` 文件中的标签,如上面的例子中有 `//localhost/myshare2` + + 提示如下面,表示 Samba 服务启动成功 + ``` + Domain=[xxx1] OS=[Windows 6.1] Server=[Samba 4.6.2] + + Sharename Type Comment + --------- ---- ------- + share1 Disk + IPC$ IPC IPC Service (Samba 4.6.2) + Domain=[xxx1] OS=[Windows 6.1] Server=[Samba 4.6.2] + + Server Comment + --------- ------- + + Workgroup Master + --------- ------- + xxx2 xxx1 + WORKGROUP xxx3 + + ``` +- Windows 登录 + 打开资源管理器 -> 映射网络驱动器 -> 文件夹 填写上述 `smbclient –L` 命令后面加的路径 -> + 弹出用户名密码对话框 -> 登录成功 + + +## Samba 登录失败 + +- linux 防火墙 + +- Windows 用户密码都正确,错误提示‘未知的用户名和密码。’ + regedit 打开注册表,删除键值 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa 中的 LMCompatibilityLevel,无需重启计算机 + +## Samba 资料 + +- +- +- +- +- +- +- +- diff --git a/Sed.md b/markdown-file/Sed.md similarity index 94% rename from Sed.md rename to markdown-file/Sed.md index ae5cdea6..fd5b73a6 100644 --- a/Sed.md +++ b/markdown-file/Sed.md @@ -1,6 +1,6 @@ # Sed 常用命令 -- 轻量级流编辑器,一般用来处理文本类文件 +- 轻量级流编辑器,一般用来处理文本类文件 - **sed 是非交互式的编辑器。它不会修改文件,除非使用 shell 重定向来保存结果。默认情况下,所有的输出行都被打印到屏幕上** - **用 sed -i 会实际写入**,下面为了演示,都没加该参数,有需要可以自行添加。 @@ -53,16 +53,6 @@ rootLogger.appenderRef.rolling.ref = rolling - `sed 's/^[0-9][0-9]*//g' /opt/log4j2.properties`:将文件中每一行以数字开头,都替换掉空字符并展示 - `sed '4,6s/^/#/g' /opt/log4j2.properties`:将文件中 4 ~ 6 行添加 # 开头 - `sed '4,6s/^#//g' /opt/log4j2.properties`:将文件中 4 ~ 6 行 # 开头去掉 -- ``: -- ``: -- ``: -- ``: -- ``: -- ``: -- ``: -- ``: -- ``: -- ``: ## 实用例子 @@ -70,14 +60,7 @@ rootLogger.appenderRef.rolling.ref = rolling - `ifconfig eth0 |grep 'inet addr' |sed 's/^.*addr://g' |sed 's/Bcast.*$//g'`:CentOS 6 只显示 IP - `ifconfig ens33 |grep 'inet' |sed 's/^.*inet//g' |sed 's/netmask.*$//g' |sed -n '1p'`:CentOS 7.3 只显示 IP。先用 grep 筛选中包含 inet 的数据。 - `s` 参数开头表示的是搜索替换,`/^.*inet` 表示从开头到 inet 之间,`//` 为空内容,`/g`,表示处理这一行所有匹配的内容。`/netmask.*$` 表示从 netmask 到这一行结束的内容 -- ``: -- ``: -- ``: -- ``: -- ``: -- ``: -- ``: -- ``: + diff --git a/Shell.md b/markdown-file/Shell.md similarity index 100% rename from Shell.md rename to markdown-file/Shell.md diff --git a/markdown-file/Showdoc-Install-And-Settings.md b/markdown-file/Showdoc-Install-And-Settings.md new file mode 100644 index 00000000..9d5cc9b7 --- /dev/null +++ b/markdown-file/Showdoc-Install-And-Settings.md @@ -0,0 +1,24 @@ +# Showdoc 安装和配置 + +## Showdoc 介绍 + +- 官网: +- Github: +- 当前(201804)最新版:2.0.7 + +## Docker 下安装 Showdoc + +- 场景: + - 我的 git 数据目录地址 /opt/git-data +- clone 官网源码:`git clone --depth=1 https://github.com/star7th/showdoc.git` +- 进入源码目录:`cd /opt/git-data/showdoc` +- 构建 docker 镜像:`docker build -t showdoc ./` +- 运行镜像:`docker run -d --name showdoc -p 4999:80 showdoc` +- 浏览器输入:`http://47.106.127.131:4999/install`,进行程序的初始化,其实就是让你选择语言和几个提示 +- 注意: + - 容器中的数据存放目录为:`/var/www/html`,其中 + - 数据库文件:`/var/www/html/Sqlite/sqlite.db.php` + - 图片:`/var/www/html/Public/Uploads` + - 后续需要升级系统,更换服务器需要迁移这两个目录下的文件。我尝试挂载这两个目录,但是发现出现各种问题解决不了,所以就不管了。 +- 网站首页地址: + - 没有什么系统管理员用户的概念,需要自己注册 \ No newline at end of file diff --git a/markdown-file/SkyWalking-Install-And-Settings.md b/markdown-file/SkyWalking-Install-And-Settings.md new file mode 100644 index 00000000..db9cf77c --- /dev/null +++ b/markdown-file/SkyWalking-Install-And-Settings.md @@ -0,0 +1,202 @@ +# SkyWalking 安装和配置 + + +## OpenAPM 相关 + +- 目前市场工具一览: +- 目前最活跃的标准:[OpenTracing](https://opentracing.io/) +- 现在比较活跃的应该是: + - [Jaeger](https://www.jaegertracing.io/) + - [SkyWalking](https://skywalking.apache.org/) + + +## 官网资料 + +- 当前时间:2019-05,最新版本:6.1 +- 官网: +- 官网 Github: +- 官网文档: +- 官网下载: + - 该网页显示:官网目前推荐的是通过源码构建出包,docker 镜像推荐 + - 源码构建方法: +- 这里简单抽取下核心内容: +- 至少需要 jdk8 + maven3 +- 需要 Elasticsearch + - Elasticsearch 和 SkyWalking 的所在服务器的时间必须一致 + - 看了下源码依赖的 Elasticsearch 依赖包,目前支持 5.x 和 6.x + + +## 支持收集的组件列表 + +- 国内常用的组件目前看来都支持了 +- + + +## 基于 IntelliJ IDEA 直接运行、Debug + +- 这里选择 IntelliJ IDEA 运行服务,方便我们 debug 了解 SkyWalking: + +``` +cd skywalking/ + +git submodule init + +git submodule update + +mvn clean package -DskipTests + +因为需要设置 gRPC 的自动生成的代码目录,为源码目录,所以: +手工将下面提到的目录下的 grpc-java 和 java 目录设置为 IntelliJ IDEA 的源码目录(Sources Root) +/skywalking/apm-protocol/apm-network/target/generated-sources/protobuf +/skywalking/oap-server/server-core/target/generated-sources/protobuf +/skywalking/oap-server/server-receiver-plugin/receiver-proto/target/generated-sources/protobuf +/skywalking/oap-server/exporter/target/generated-sources/protobuf + + +手工将下面提到的目录下的 antlr4 目录设置为 IntelliJ IDEA 的源码目录(Sources Root) +/skywalking/oap-server/generate-tool-grammar/target/generated-sources + +手工将下面提到的目录下的 oal 目录设置为 IntelliJ IDEA 的源码目录(Sources Root) +/skywalking/oap-server/generated-analysis/target/generated-sources + +``` + +#### 启动 Server 项目 + +- 现在可以通过 IntelliJ IDEA 启动服务: +- 编辑 server 配置:`/skywalking/oap-server/server-starter/src/main/resources/application.yml` + - 里面有关 Elasticsearch 连接信息的配置,你可以根据自己的情况进行配置。 +- 启动类:`/skywalking/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/OAPServerStartUp.java` + - 第一次启动会创建 540 个左右的 Elasticsearch 索引库,会花点时间。 + + +#### 启动 UI 项目 + + +- 现在启动 UI 项目,找到:`/skywalking/apm-webapp/src/main/java/org/apache/skywalking/apm/webapp/ApplicationStartUp.java` +- 访问 UI 地址: + - 用户名:admin + - 密码:admin + + +## Java Agent(探针) + + +#### IntelliJ IDEA 项目调试 + +- 前面构建服务的时候记得构建出 jar 包出来,这里要用到 +- 自己的 Spring Boot 项目 +- 引包: + +``` + + + + org.apache.skywalking + apm-toolkit-trace + 6.1.0 + + +``` + +- 常用注解: + + +``` +@Trace +@ApiOperation(tags = {"用户系统管理->用户管理->用户列表"}, value = "查询所有用户列表", notes = "查询所有用户列表") +@RequestMapping(value = "/list", method = RequestMethod.GET) +@ResponseBody +public List list() { + List sysUserList = sysUserService.findAll(); + ActiveSpan.tag("一共有数据:", sysUserList.size() + "条"); + log.info("当前 traceId={}", TraceContext.traceId()); + return sysUserList; +} + +``` + +- 更多注解的使用: + +- 你的 demo 项目在 IntelliJ IDEA 启动的时候加上 VM 参数上设置: + +``` +-javaagent:/你自己的路径/skywalking-agent.jar -Dskywalking.agent.application_code=my_app_001 -Dskywalking.collector.backend_service=localhost:11800 +``` + +- 默认 11800 是 gRPC 的接收接口 +- 你自己构建出来的 jar 路径一般是:`/skywalking/apm-sniffer/apm-agent/target/skywalking-agent.jar` +- 然后请求你带有 Trace 的 Controller,然后去 UI 界面看统计情况 + +#### jar 包方式 + +- 你的 Spring Boot jar 包 run 之前加上 VM 参数: + +``` +java -javaagent:/你自己的路径/skywalking-agent.jar -Dskywalking.collector.backend_service=localhost:11800 -Dskywalking.agent.application_code=my_app_002 -jar my-project-1.0-SNAPSHOT.jar +``` + + +#### Docker 方式 + +- Dockerfile + +``` +FROM openjdk:8-jre-alpine + +LABEL maintainer="tanjian20150101@gmail.com" + +ENV SW_AGENT_NAMESPACE=java-agent-demo \ + SW_AGENT_COLLECTOR_BACKEND_SERVICES=localhost:11800 + +COPY skywalking-agent /apache-skywalking-apm-bin/agent + +COPY target/sky-demo-1.0-SNAPSHOT.jar /demo.jar + +ENTRYPOINT java -javaagent:/apache-skywalking-apm-bin/agent/skywalking-agent.jar -jar /demo.jar +``` + +- 构建镜像: + +``` +docker build -t hello-demo . +docker run -p 10101:10101 -e SW_AGENT_NAMESPACE=hello-world-demo-005 -e SW_AGENT_COLLECTOR_BACKEND_SERVICES=127.10.0.2:11800 hello-demo +``` + + + +## 构建 jar 部署在服务器 + +- 如果想直接打包出 jar 部署与服务器,只需要这样: + +``` +cd skywalking/ + +git submodule init + +git submodule update + +mvn clean package -DskipTests +``` + +## 告警配置 + +- + + +## 资料 + +- +- +- +- +- <> +- <> +- <> +- <> + + + + + + diff --git a/Solr-Install-And-Settings.md b/markdown-file/Solr-Install-And-Settings.md similarity index 100% rename from Solr-Install-And-Settings.md rename to markdown-file/Solr-Install-And-Settings.md diff --git a/markdown-file/SonarQube-Install-And-Usage.md b/markdown-file/SonarQube-Install-And-Usage.md new file mode 100644 index 00000000..52b5e0cd --- /dev/null +++ b/markdown-file/SonarQube-Install-And-Usage.md @@ -0,0 +1,222 @@ + + +# SonarQube 使用 + +## 环境说明 + +- CentOS 7.3 +- 不建议在 Windows 上使用 + +## SonarQube 基本概念 + +- 官网: +- 官网下载: +- Github 主页(主要是用 Java 开发): +- 当前(2018-02)最新 LTS 是:6.7.1,最新发布版本:7.0 +- 主要支持的语言项目有: + +``` +C/C++ +JavaScript +C# +Java +COBOL +TypeScript +PL/SQL +PL/I +PHP +ABAP +T-SQL +VB.NET +VB6 +Python +RPG +Flex +Objective-C +Swift +Web(HTML and JSF/JSP) +XML +``` + +## Docker 的 SonarQube 安装和基本配置 + +#### 简单 docker 方式 + +- 一个命令(没有挂载):`docker run -d --name sonarqube -p 19000:9000 -p 19092:9092 -e "TZ=Asia/Shanghai" -e SONARQUBE_JDBC_USERNAME=sonar -e SONARQUBE_JDBC_PASSWORD=sonar -e SONARQUBE_JDBC_URL=jdbc:postgresql://112.74.49.55:5433/sonar sonarqube` +- 一个命令(有挂载):`docker run -d --name sonarqube -p 19000:9000 -p 19092:9092 -v /data/docker/ci/sonarqube/conf:/opt/sonarqube/conf -v /data/docker/ci/sonarqube/data:/opt/sonarqube/data -v /data/docker/ci/sonarqube/extension:/opt/sonarqube/extensions -v /data/docker/ci/sonarqube/bundled-plugins:/opt/sonarqube/lib/bundled-plugins -e "TZ=Asia/Shanghai" -e SONARQUBE_JDBC_USERNAME=sonar -e SONARQUBE_JDBC_PASSWORD=sonar -e SONARQUBE_JDBC_URL=jdbc:postgresql://120.79.2.92:5433/sonar sonarqube` + + + +- 在浏览器里打开: +- 管理员用户名、密码都是:`admin` + +#### docker-compose 方式 + +- 官网文档: + +``` +postgresql: + restart: always + image: sameersbn/postgresql:9.6-2 + ports: + - "5433:5432" + environment: + - DB_USER=sonar + - DB_PASS=sonar + - DB_NAME=sonar + - DB_EXTENSION=pg_trgm + volumes: + - /data/docker/ci/postgresql:/var/lib/postgresql +sonarqube: + restart: always + image: sonarqube + ports: + - "19000:9000" + - "19092:9092" + links: + - postgresql:postgresql + depends_on: + - postgresql + environment: + - SONARQUBE_JDBC_URL=jdbc:postgresql://postgresql:5433/sonar + - SONARQUBE_JDBC_USERNAME=sonar + - SONARQUBE_JDBC_PASSWORD=sonar + volumes: + - /data/docker/ci/sonarqube/conf:/opt/sonarqube/conf + - /data/docker/ci/sonarqube/data:/opt/sonarqube/data + - /data/docker/ci/sonarqube/extension:/opt/sonarqube/extensions + - /data/docker/ci/sonarqube/bundled-plugins:/opt/sonarqube/lib/bundled-plugins +``` + + +- 一整套完整服务: + +``` +version: '3' + +networks: + prodnetwork: + driver: bridge + +services: + nexus: + image: sonatype/nexus3 + ports: + - 8081:8081 + networks: + - prodnetwork + + jenkins: + image: jenkins + ports: + - 8080:8080 + networks: + - prodnetwork + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /usr/local/bin/docker:/usr/bin/docker + - /opt/jenkins/:/var/lib/jenkins/ + links: + - nexus + - gitlab + - sonar + environment: + - NEXUS_PORT=8081 + - SONAR_PORT=9000 + - SONAR_DB_PORT=5432 + + sonar: + image: sonarqube + ports: + - 9000:9000 + networks: + - prodnetwork + links: + - sonardb + environment: + - SONARQUBE_JDBC_URL=jdbc:postgresql://sonardb:5432/sonar + - SONARQUBE_JDBC_USERNAME=sonar + - SONARQUBE_JDBC_PASSWORD=sonar + sonardb: + networks: + - prodnetwork + image: postgres + ports: + - 5432:5432 + environment: + - POSTGRES_DB=sonar + - POSTGRES_USER=sonar + - POSTGRES_PASSWORD=sonar + volumes: + - /opt/postgres/data:/var/lib/postgresql/data + + gitlab: + image: gitlab/gitlab-ce + restart: always + networks: + - prodnetwork + environment: + GITLAB_OMNIBUS_CONFIG: | + # external_url 'https://gitlab.example.com' + # Add any other gitlab.rb configuration here, each on its own line + ports: + - 80:80 + - 443:443 + - 2222:22 + volumes: + - /opt/gitlab/config:/etc/gitlab + - /opt/gitlab/logs:/var/log/gitlab + - /opt/gitlab/data:/var/opt/gitlab +``` + + + +## SonarQube 插件 + +这里我安装的插件: + +chinese 中文支持 +php php代码支持 +Android Android支持 +安装成功后,重启 sonarqube 服务,再次访问 http://ip:9000/ 即可看到中文界面 + + +## 与 Jenkins 集成 + +用 admin 用户登陆 sonarQube,【配置】–>【权限】 –>【用户】 +输入admin,得到token,复制此token +jenkins安装sonar相关插件 +Jenkins 点击【系统管理】 –> 【系统设置]】 配置 Sonar,设置完保存 + + +## 资料 + +- +- +- <> +- <> +- <> + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/markdown-file/Spark-Install-And-Settings.md b/markdown-file/Spark-Install-And-Settings.md new file mode 100644 index 00000000..004ce09c --- /dev/null +++ b/markdown-file/Spark-Install-And-Settings.md @@ -0,0 +1,49 @@ +# Spark 安装和配置 + +## 介绍 + +- 2018-12 发布最新:2.4.0 版本 +- 官网: +- 官网文档: +- 官网下载: +- 官网 Github: + +## 本地模式安装 + +- CentOS 7.4 +- IP 地址:`192.168.0.105` +- 必须 JDK 8.x +- 已经安装了 hadoop-2.6.5 集群(**这个细节注意**) +- 因为个人原因,我这里 Hadoop 还是 2.6.5 版本,Spark 要用的是 2.2.0 +- Spark 2.2.0 官网文档: + - 192M,下载速度有点慢 + - `cd /usr/local && wget https://archive.apache.org/dist/spark/spark-2.2.0/spark-2.2.0-bin-hadoop2.6.tgz` +- 解压:`tar zxvf spark-2.2.0-bin-hadoop2.6.tgz` +- 重命名:`mv /usr/local/spark-2.2.0-bin-hadoop2.6 /usr/local/spark` +- 增加环境变量: + +``` +vim /etc/profile + +SPARK_HOME=/usr/local/spark +PATH=$PATH:${SPARK_HOME}/bin:${SPARK_HOME}/sbin +export SPARK_HOME +export PATH + +source /etc/profile +``` + +- 修改配置:`cp $SPARK_HOME/conf/spark-env.sh.template $SPARK_HOME/conf/spark-env.sh` +- 修改配置:`vim $SPARK_HOME/conf/spark-env.sh` +- 假设我的 hadoop 路径是:/usr/local/hadoop-2.6.5,则最尾巴增加: + +``` +export HADOOP_CONF_DIR=/usr/local/hadoop-2.6.5/etc/hadoop +``` + +- 因为要交给 YARN 作业,所以到这里就好了。 + + +## 资料 + +- diff --git a/TeamCity-Install-And-Settings.md b/markdown-file/TeamCity-Install-And-Settings.md similarity index 100% rename from TeamCity-Install-And-Settings.md rename to markdown-file/TeamCity-Install-And-Settings.md diff --git a/Thrift-Install-And-Usage.md b/markdown-file/Thrift-Install-And-Usage.md similarity index 100% rename from Thrift-Install-And-Usage.md rename to markdown-file/Thrift-Install-And-Usage.md diff --git a/Tmux-Install-And-Settings.md b/markdown-file/Tmux-Install-And-Settings.md similarity index 100% rename from Tmux-Install-And-Settings.md rename to markdown-file/Tmux-Install-And-Settings.md diff --git a/Tomcat-Install-And-Settings.md b/markdown-file/Tomcat-Install-And-Settings.md similarity index 52% rename from Tomcat-Install-And-Settings.md rename to markdown-file/Tomcat-Install-And-Settings.md index e00035cb..beeedd53 100644 --- a/Tomcat-Install-And-Settings.md +++ b/markdown-file/Tomcat-Install-And-Settings.md @@ -58,131 +58,194 @@ - Tomcat 7 文档: - Tomcat 8 文档: - 如果你需要查看 Tomcat 的运行状态可以配置tomcat管理员账户,然后登陆 Tomcat 后台进行查看 -- 编辑 /opt/tomcat7/bin/conf/tomcat-users.xml 文件,在里面添加下面信息: +- 编辑 /opt/tomcat8/bin/conf/tomcat-users.xml 文件,在里面添加下面信息: + ``` xml - + - - - + + + +``` +- 编辑配置文件:`vim /usr/program/tomcat8/conf/server.xml` + +#### 打开默认被注释的连接池配置 + +- 默认值: + +``` xml + ``` -- 编辑配置文件:`vim /usr/program/tomcat7/conf/server.xml` - - 打开默认被注释的连接池配置: - - 默认值: - ``` xml - - ``` - - 修改为: - ``` xml - - ``` - - 重点参数解释: - - maxThreads,最大并发数,默认设置 200,一般建议在 500 ~ 800,根据硬件设施和业务来判断 - - minSpareThreads,Tomcat 初始化时创建的线程数,默认设置 25 - - prestartminSpareThreads,在 Tomcat 初始化的时候就初始化 minSpareThreads 的参数值,如果不等于 true,minSpareThreads 的值就没啥效果了 - - maxQueueSize,最大的等待队列数,超过则拒绝请求 - - maxIdleTime,如果当前线程大于初始化线程,那空闲线程存活的时间,单位毫秒,默认60000=60秒=1分钟。 - - 修改默认的链接参数配置: - - 默认值: - ``` xml - - ``` - - 修改为: - ``` xml - - ``` - - 重点参数解释: - - protocol,Tomcat 8 设置 nio2 更好:org.apache.coyote.http11.Http11Nio2Protocol(如果这个用不了,就用下面那个) - - protocol,Tomcat 6、7 设置 nio 更好:org.apache.coyote.http11.Http11NioProtocol - - enableLookups,禁用DNS查询 - - acceptCount,指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理,默认设置 100 - - maxPostSize,以 FORM URL 参数方式的 POST 提交方式,限制提交最大的大小,默认是 2097152(2兆),它使用的单位是字节。10485760 为 10M。如果要禁用限制,则可以设置为 -1。 - - acceptorThreadCount,用于接收连接的线程的数量,默认值是1。一般这个指需要改动的时候是因为该服务器是一个多核CPU,如果是多核 CPU 一般配置为 2. - - maxHttpHeaderSize,http请求头信息的最大程度,超过此长度的部分不予处理。一般8K。 - - 禁用 AJP(如果你服务器没有使用 Apache) - - 把下面这一行注释掉,默认 Tomcat 是开启的。 - ``` xml - - ``` - - - -## JVM 优化 + +- 修改为: + +``` xml + +``` + +- 重点参数解释: + - maxThreads,最大并发数,默认设置 200,一般建议在 500 ~ 800,根据硬件设施和业务来判断 + - minSpareThreads,Tomcat 初始化时创建的线程数,默认设置 25 + - prestartminSpareThreads,在 Tomcat 初始化的时候就初始化 minSpareThreads 的参数值,如果不等于 true,minSpareThreads 的值就没啥效果了 + - maxQueueSize,最大的等待队列数,超过则拒绝请求 + - maxIdleTime,如果当前线程大于初始化线程,那空闲线程存活的时间,单位毫秒,默认60000=60秒=1分钟。 + +#### 修改默认的链接参数配置 + +- 默认值: + +``` xml + +``` + +- 修改为: + +``` xml + +``` + +- 重点参数解释: + - protocol,Tomcat 8 设置 nio2 更好:org.apache.coyote.http11.Http11Nio2Protocol(如果这个用不了,就用下面那个) + - protocol,Tomcat 6、7 设置 nio 更好:org.apache.coyote.http11.Http11NioProtocol + - enableLookups,禁用DNS查询,tomcat 8 默认已经是禁用了。 + - maxConnections,最大连接数,tomcat 8 默认设置 10000 + - acceptCount,指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理,默认设置 100 + - maxPostSize,以 FORM URL 参数方式的 POST 提交方式,限制提交最大的大小,默认是 2097152(2兆),它使用的单位是字节。10485760 为 10M。如果要禁用限制,则可以设置为 -1。 + - maxHttpHeaderSize,http请求头信息的最大程度,超过此长度的部分不予处理。一般8K。 +- 禁用 AJP(如果你服务器没有使用 Apache) + - 把下面这一行注释掉,默认 Tomcat 是开启的。 + +``` xml + +``` + +- 关闭自动部署功能: +- 旧值: +``` + +``` + +- 新值: +``` + +``` + +## JVM 优化(JDK 8) - 模型资料来源: - 配比资料: -- Java 的内存模型分为: - - Young,年轻代(易被 GC)。Young 区被划分为三部分,Eden 区和两个大小严格相同的 Survivor 区,其中 Survivor 区间中,某一时刻只有其中一个是被使用的,另外一个留做垃圾收集时复制对象用,在 Young 区间变满的时候,minor GC 就会将存活的对象移到空闲的Survivor 区间中,根据 JVM 的策略,在经过几次垃圾收集后,任然存活于 Survivor 的对象将被移动到 Tenured 区间。 - - Tenured,终身代。Tenured 区主要保存生命周期长的对象,一般是一些老的对象,当一些对象在 Young 复制转移一定的次数以后,对象就会被转移到 Tenured 区,一般如果系统中用了 application 级别的缓存,缓存中的对象往往会被转移到这一区间。 - - Perm,永久代。主要保存 class,method,filed 对象,这部门的空间一般不会溢出,除非一次性加载了很多的类,不过在涉及到热部署的应用服务器的时候,有时候会遇到 java.lang.OutOfMemoryError : PermGen space 的错误,造成这个错误的很大原因就有可能是每次都重新部署,但是重新部署后,类的 class 没有被卸载掉,这样就造成了大量的 class 对象保存在了 perm 中,这种情况下,一般重新启动应用服务器可以解决问题。 -- Linux 修改 /usr/program/tomcat7/bin/catalina.sh 文件,把下面信息添加到文件第一行。 - - 如果服务器只运行一个 Tomcat +- JDK8 配比:[关键系统的JVM参数推荐(2018仲夏版)](https://mp.weixin.qq.com/s/FHY0MelBfmgdRpT4zWF9dQ) +- JDK8 常用配比总结 8G 内存:`CATALINA_OPTS="-Dfile.encoding=UTF-8 -Xms4g -Xmx4g"` +- Java 的内存模型看:[这篇文章](Java-bin.md) +- Linux 修改 /usr/program/tomcat8/bin/catalina.sh 文件,把下面信息添加到文件第一行。 + - 如果服务器只运行一个 Tomcat,堆栈信息可以这样配置: - 机子内存如果是 4G: - - `CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms2048m -Xmx2048m -Xmn1024m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10 -XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC"` + - `CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms2g -Xmx2g"` - 机子内存如果是 8G: - - `CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms4096m -Xmx4096m -Xmn2048m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10 -XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC"` + - `CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms4g -Xmx4g"` - 机子内存如果是 16G: - - `CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms8192m -Xmx8192m -Xmn4096m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10 -XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC"` + - `CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms8g -Xmx8g"` - 机子内存如果是 32G: - - `CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms16384m -Xmx16384m -Xmn8192m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10 -XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC"` + - `CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms16g -Xmx16g"` - 如果是 8G 开发机 - - `-Xms2048m -Xmx2048m -XX:NewSize=512m -XX:MaxNewSize=1024m -XX:PermSize=256m -XX:MaxPermSize=512m` + - `-Xms2g -Xmx2g` - 如果是 16G 开发机 - - `-Xms4096m -Xmx4096m -XX:NewSize=1024m -XX:MaxNewSize=2048m -XX:PermSize=256m -XX:MaxPermSize=512m` - - 参数说明: - ``` nginx - -Dfile.encoding:默认文件编码 - -server:表示这是应用于服务器的配置,JVM 内部会有特殊处理的 - -Xmx1024m:设置JVM最大可用内存为1024MB - -Xms1024m:设置JVM最小内存为1024m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。 - -Xmn1024m:设置JVM新生代大小(JDK1.4之后版本)。一般-Xmn的大小是-Xms的1/2左右,不要设置的过大或过小,过大导致老年代变小,频繁Full GC,过小导致minor GC频繁。如果不设置-Xmn,可以采用-XX:NewRatio=2来设置,也是一样的效果 - -XX:NewSize:设置新生代大小 - -XX:MaxNewSize:设置最大的新生代大小 - -XX:PermSize:设置永久代大小(在 Tomcat8 移出了该参数) - -XX:MaxPermSize:设置最大永久代大小(在 Tomcat8 移出了该参数) - -XX:NewRatio=4:设置年轻代(包括 Eden 和两个 Survivor 区)与终身代的比值(除去永久代)。设置为 4,则年轻代与终身代所占比值为 1:4,年轻代占整个堆栈的 1/5 - -XX:MaxTenuringThreshold=10:设置垃圾最大年龄,默认为:15。如果设置为 0 的话,则年轻代对象不经过 Survivor 区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在 Survivor 区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。需要注意的是,设置了 -XX:MaxTenuringThreshold,并不代表着,对象一定在年轻代存活15次才被晋升进入老年代,它只是一个最大值,事实上,存在一个动态计算机制,计算每次晋入老年代的阈值,取阈值和MaxTenuringThreshold中较小的一个为准。 - -XX:+DisableExplicitGC:这个将会忽略手动调用 GC 的代码使得 System.gc() 的调用就会变成一个空调用,完全不会触发任何 GC - ``` + - `-Xms4g -Xmx4g` + - 还有一个参数:`-XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=512M` + - 这个可以通过调试来确认什么值合适,一般通过使用 `jstat -gc PID 250 20`,查看 gc 情况下的 MC、MU 情况。 + - 默认 MaxMetaspaceSize 是 -1,无上限,所以如果硬件还行,不配置也没啥问题。 + - 自己也了解 JVM 实际情况,那就根据实际情况调整。一般项目可以推荐:`-XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=512M` - Windows 修改 /tomcat7/bin/catalina.bat 文件,找到这一行:`echo Using CATALINA_BASE: "%CATALINA_BASE%"`,然后在其上面添加如下内容,此方法只对解压版的 Tomcat 有效果,对于安装版本的需要点击安装后任务栏上的那个 Tomcat 图标,打开配置中有一个 `Java` Tab 的进行编辑。 ``` nginx set JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding="UTF-8" -Dsun.jnu.encoding="UTF8" -Ddefault.client.encoding="UTF-8" -Duser.language=Zh -set JAVA_OPTS=%JAVA_OPTS% -server -Xms4096m -Xmx4096m -Xmn2048m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10 -XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC +set JAVA_OPTS=%JAVA_OPTS% -server -Xms4g -Xmx4g ``` +## tomcat-manager 监控配置(tomcat 8.0.53) + +#### 开启步骤 + +- 不同的 Tomcat 版本会有差异。 +- 官网文档: +- **先确保解压的 tomcat/webapps 下有 manager 项目** +- 在配置文件里面添加可访问用户:`vim /usr/local/tomcat8/conf/tomcat-users.xml`,比如: + +``` + + + + + +``` + +- 正常情况下,manager ui 界面只运行内网:127.0.0.1 访问,这里我们要关闭这个限制。 +- 修改 webapps 下 manager 项目下的配置:`vim /usr/local/tomcat8/webapps/manager/META-INF/context.xml` +- 旧值: + +``` + + + + + diff --git a/Ubuntu-Install-VMware.md b/markdown-file/Ubuntu-Install-VMware.md similarity index 100% rename from Ubuntu-Install-VMware.md rename to markdown-file/Ubuntu-Install-VMware.md diff --git a/Ubuntu-Install.md b/markdown-file/Ubuntu-Install.md similarity index 94% rename from Ubuntu-Install.md rename to markdown-file/Ubuntu-Install.md index f76190bb..4347efab 100644 --- a/Ubuntu-Install.md +++ b/markdown-file/Ubuntu-Install.md @@ -1,8 +1,8 @@ # Ubuntu 安装和分区 -- 先下载该系列教程: +- 先下载该系列教程(提取码:8qfg): -![Ubuntu 安装和分区视频](images/Ubuntu-a-1.jpg) +![Ubuntu 安装和分区视频](../images/Ubuntu-a-1.jpg) - 找到如图箭头目录上的两个视频,并看完,你对 Ubuntu 的安装就有了一个大概的了解,视频中 Ubuntu 虽然版本较早 13.04 的, 但是没关系,对于 Ubuntu 来讲新旧版本安装基本都一样的,所以别担心,驱动的问题也别担心,我们不是要在 Ubuntu 打游戏的,所以常见驱动系统是已经帮我们集成的不会影响使用。但是分区这一块的话,我个人建议是手工分区,视频中没有最终执行手动分区,只是演示了一下又返回了。 我个人是要求你手动分区的。 @@ -15,7 +15,7 @@ - 好了假设你现在已经格式化好 U 盘,现在可以开始讲分区了。这里特别说明的是有多个硬盘的,多块硬盘分区方案就没视频中那么简单,特别是 Linux 的盘符不了解的就更加难了,所以看下图: -![Ubuntu 安装和分区视频](images/Ubuntu-a-2.jpg) +![Ubuntu 安装和分区视频](../images/Ubuntu-a-2.jpg) - 以我这边为例:我这边机子的硬盘是:一个 128 G 固态 + 500 G 的机械,我给一个分区方案给你们参考。下面的内容需要你先看过视频才能看懂: diff --git a/Ubuntu-Popular-Software.md b/markdown-file/Ubuntu-Popular-Software.md similarity index 63% rename from Ubuntu-Popular-Software.md rename to markdown-file/Ubuntu-Popular-Software.md index 51af8f8f..5f22a8c9 100644 --- a/Ubuntu-Popular-Software.md +++ b/markdown-file/Ubuntu-Popular-Software.md @@ -3,13 +3,21 @@ ## 安装软件基础 - 取回更新的软件包列表信息:`sudo apt-get update`,如果安装某个软件报:`Unable to locate package`,就得这样 update 下。 +- 安装本地 deb 文件:`sudo dpkg -i 文件名` + - 安装过程提示缺依赖:`sudo apt-get --fix-broken install -y` - 查看已经安装了哪些包:`sudo dpkg -l` - 查看已安装列表中是否有 Vim 软件,没有安装则没有数据显示:`sudo dpkg -l | grep vim` - 查看 Vim 软件安装位置:`sudo dpkg -L vim` - 安装名为 Vim 的软件:`sudo apt-get install vim` -- 卸载名为 Vim 的软件(保留配置文档):`sudo apt-get remove vim` -- 卸载名为 Vim 的软件(删除配置文档):`sudo apt-get –purge remove vim` - 升级系统所有有新版本的软件:`sudo apt-get upgrade` + +## 卸载 + +- 卸载名为 Vim 的软件(保留配置文档):`sudo apt-get remove vim`(在输入软件的名的时候,可以输入部分,按 Tab 进行提示) +- 卸载名为 Vim 的软件(并删除配置文档):`sudo apt-get –purge remove vim` +- 卸载名为 Vim 的软件(并删除包及其依赖的软件包、配置文件):`sudo apt-get autoremove --purge vim` +- 卸载名为 Vim 的软件(dpkg 方式):`sudo dpkg -r vim`(在输入软件的名的时候,可以输入部分,按 Tab 进行提示) +- 卸载名为 Vim 的软件(dpkg 方式,并删除配置文档):`sudo dpkg -P vim` - 删除已下载的旧包文件:`sudo apt-get autoclean` - 删除所有已下载的包文件:`sudo apt-get clean` - 卸载所有自动安装且不再使用的软件包:`sudo apt-get autoremove` diff --git a/Ubuntu-Specific-Command.md b/markdown-file/Ubuntu-Specific-Command.md similarity index 100% rename from Ubuntu-Specific-Command.md rename to markdown-file/Ubuntu-Specific-Command.md diff --git a/Ubuntu.md b/markdown-file/Ubuntu.md similarity index 100% rename from Ubuntu.md rename to markdown-file/Ubuntu.md diff --git a/VPN.md b/markdown-file/VPN.md similarity index 100% rename from VPN.md rename to markdown-file/VPN.md diff --git a/Vim-Install-And-Settings.md b/markdown-file/Vim-Install-And-Settings.md similarity index 89% rename from Vim-Install-And-Settings.md rename to markdown-file/Vim-Install-And-Settings.md index d2540a62..dfdd3653 100644 --- a/Vim-Install-And-Settings.md +++ b/markdown-file/Vim-Install-And-Settings.md @@ -30,7 +30,7 @@ - `l`,右 - `v`,按 v 之后按方向键可以选中你要选中的文字 - `gg`,跳到第 1 行 - - `G`,跳到第最后行 + - `G`,跳到最后一行 - `16G` 或 `:16`,跳到第 16 行 - `$`,到本行 **行尾** - `0`,到本行 **行头** @@ -64,6 +64,7 @@ - `d$`,删除光标至 **行尾** 所有字符 - `dG`,删除光标至 **文件尾** 所有字符 - `3dd`,从当前光标开始,删掉 3 行 + - `echo > aa.txt`,从 bash 角度清空文件内容,这个比较高效 - 复制 - `y`,复制光标所选字符 - `yw`,复制光标后单词 @@ -93,13 +94,13 @@ - `:s/YouMeek/Judasn/`,把光标当前行第一个 YouMeek 替换为 Judasn - `:s/YouMeek/Judasn/g`,把光标当前行所有 YouMeek 替换为 Judasn - `:s#YouMeek/#Judasn/#`,除了使用斜杠作为分隔符之外,还可以使用 # 作为分隔符,此时中间出现的 / 不会作为分隔符,该命令表示:把光标当前行第一个 YouMeek/ 替换为 Judasn/ - - `:10,31s/YouMeek/Judasng`,把第 10 行到 31 行之间所有 YouMeek 替换为 Judasn + - `:10,31s/YouMeek/Judasn/g`,把第 10 行到 31 行之间所有 YouMeek 替换为 Judasn ## Vim 的特殊复制、黏贴 - Vim 提供了 12 个剪贴板,分别是:`0,1,2,3,4,5,6,7,8,9,a,"`,默认采用的是 `"`,也就是双引号,可能你初读感觉很奇怪。你可以用 Vim 编辑某个文件,然后输入:`:reg`。你可以看到如下内容: - - ![vim](images/Vim-Cut-And-Paste-a-1.png) + - ![vim](../images/Vim-Cut-And-Paste-a-1.png) - 复制到某个剪切板的命令:`"7y`,表示使用 7 号剪切板。 - 黏贴某个剪切板内容:`"7p`,表示使用 7 号剪切板内容进行黏贴 @@ -112,6 +113,13 @@ - 在假设你已经备份好你的 Vim 配置文件后,使用该配置文件:`curl https://raw.githubusercontent.com/wklken/vim-for-server/master/vimrc > ~/.vimrc` - 效果如下: - ![vim-for-server](https://raw.githubusercontent.com/wklken/gallery/master/vim/vim-for-server.png) +- 需要特别注意的是,如果你平时粘贴内容到终端 Vim 出现缩进错乱,一般需要这样做: + - 进入 vim 后,按 `F5`,然后 `shift + insert` 进行粘贴。这种事就不会错乱了。 + - 原因是:`vim ~/.vimrc` 中有一行这样的设置:`set pastetoggle=` + +## 其他常用命令 + +- 对两个文件进行对比:`vimdiff /opt/1.txt /opt/2.txt` ## 资料 diff --git a/Was-Hacked.md b/markdown-file/Was-Hacked.md similarity index 81% rename from Was-Hacked.md rename to markdown-file/Was-Hacked.md index 6f666e73..a803a05a 100644 --- a/Was-Hacked.md +++ b/markdown-file/Was-Hacked.md @@ -31,7 +31,10 @@ - 查看开放的端口,比如常用的80,22,8009,后面的箭头表示端口对应占用的程序:`netstat -lnp` - 检查某个端口的具体信息:`lsof -i :18954` - 检查启动项:`chkconfig` -- 检查定时器:`cat /etc/crontab` +- 检查定时器(重要):`cat /etc/crontab` +- 检查定时器(重要):`crontab -l` + - `vim /var/spool/cron/crontabs/root` + - `vim /var/spool/cron/root` - 检查其他系统重要文件: - `cat /etc/rc.local` - `cd /etc/init.d;ll` @@ -88,6 +91,25 @@ TOTAL:(总的流量) 12.9GB 229Mb 190Mb 193Mb - yum update openssh-server +## 实战 + +#### 挖矿程序 + +- 先查看调度任务是否有新增内容 + - `vim /var/spool/cron/root` + - `vim /var/spool/cron/crontabs/root` +- 如果有,先停止定时任务:`systemctl stop crond` +- 如果对方有去 wget curl 指定网站,则先在 hosts 里面映射为 127.0.0.1,比如:`127.0.0.1 prax0zma.ru` + - 查看当前最占用 CPU 的进程 PID,加入发现是 22935,则:`cd /proc/22935 && ll`,发现程序目录是:`/root/.tmp00/bash64` + - 我们就把该程序去掉执行任务的权限:`chmod -R -x /root/.tmp00/`,然后再 kill 掉该程序 +- 打开别人的脚本,看下是如何书写的,发现有写入几个目录,这里进行删除: + +``` +rm -rf /tmp/.ha /boot/.b /boot/.0 /root/.tmp00 +``` + +- 最后检查下是否有免密内容被修改:`cd ~/.ssh/ && cat authorized_keys` + ## 资料 - diff --git a/markdown-file/WordPress-Install-And-Settings.md b/markdown-file/WordPress-Install-And-Settings.md new file mode 100644 index 00000000..c11835da --- /dev/null +++ b/markdown-file/WordPress-Install-And-Settings.md @@ -0,0 +1,213 @@ +# WordPress 安装和配置 + +## 环境 + +- 腾讯云 +- CentOS 7.4 +- 1C + 1G(最低配置) +- IP:193.112.211.201 + - 推荐按此文章进行安装的时候可以把该 IP 替换成你的,方便直接复制 + +## 更新系统可更新软件 + +``` +yum clean all +yum -y update +``` + +## 安装 Apache + +``` +yum install -y httpd +systemctl start httpd.service +systemctl enable httpd.service +``` + +- 访问(如果出现 Apache 欢迎页面即表示成功): + + +## 安装 MySQL + +#### 先检查是否已经安装了 Mariadb + +- 检查:`rpm -qa | grep mariadb` +- 卸载:`rpm -e --nodeps mariadb-libs-5.5.56-2.el7.x86_64` + +#### MySQL 5.5 安装和配置(内存 1G 推荐) + +- [MySQL 5.5](Mysql-Install-And-Settings.md) + +#### MySQL 5.6 安装和配置(如果内存没有大于 2G,请不要使用) + +- [MySQL 5.6](Mysql-Install-And-Settings.md) + +#### MySQL 5.7(推荐) + +``` +wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm +yum localinstall -y mysql57-community-release-el7-8.noarch.rpm +yum install mysql-community-server + +systemctl enable mysqld.service +systemctl restart mysqld.service +``` + +#### MySQL 5.7 配置 + + +- 默认 MySQL 5.7 安装完有一个随机密码生成,位置在:`/var/log/mysqld.log`,里面有这样一句话:`A temporary password is generated for root@localhost: 随机密码` +- 如果初次要连上去需要填写该密码 +- 我们也可以选择重置密码: + - `systemctl stop mysqld.service` + - `/usr/sbin/mysqld --skip-grant-tables --user=mysql` +- 在启动一个终端:`mysql -u root mysql` + - `UPDATE user SET authentication_string=PASSWORD('新密码') where USER='root';FLUSH PRIVILEGES;` + - `GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '上一步的新密码' WITH GRANT OPTION;` + - `systemctl restart mysqld.service` +- 试一下:`mysql -h localhost -u root -p` 然后输入密码,在 MySQL 终端输入:`select 1;` +- 如果报:`You must reset your password using ALTER USER statement before executing this statement`,解决办法: + +``` +set global validate_password_policy=0; #密码强度设为最低等级 +set global validate_password_length=6; #密码允许最小长度为6 +set password = password('新密码'); +FLUSH PRIVILEGES; +``` + +- YUM 安装的 MySQL 默认配置文件在:`vim /etc/my.cnf`,默认有如下信息,会自己配置的可以改下。 + +``` +# For advice on how to change settings please see +# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html + +[mysqld] +# +# Remove leading # and set to the amount of RAM for the most important data +# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%. +# innodb_buffer_pool_size = 128M +# +# Remove leading # to turn on a very important data integrity option: logging +# changes to the binary log between backups. +# log_bin +# +# Remove leading # to set options mainly useful for reporting servers. +# The server defaults are faster for transactions and fast SELECTs. +# Adjust sizes as needed, experiment to find the optimal values. +# join_buffer_size = 128M +# sort_buffer_size = 2M +# read_rnd_buffer_size = 2M +datadir=/var/lib/mysql +socket=/var/lib/mysql/mysql.sock + +# Disabling symbolic-links is recommended to prevent assorted security risks +symbolic-links=0 + +log-error=/var/log/mysqld.log +pid-file=/var/run/mysqld/mysqld.pid +``` + + +## 安装 PHP 7 + +- CentOS 7 默认是 PHP 5.4,版本太低 +- 安装过程: +- 默认配置文件位置:`vim /etc/php.ini` +- 测试 PHP 安装结果,新建文件:`vim /var/www/html/info.php` + +``` + +``` + +- 浏览器访问(出现 PHP 环境信息表示安装成功): +- 测试后删除刚刚文件:`rm -rf /var/www/html/info.php` + +## 安装 WordPress + +- 寻找官网最新版本下载地址(201806 是 4.9.4): + +``` +cd /var/www/html/ + +wget https://cn.wordpress.org/wordpress-4.9.4-zh_CN.zip + +unzip wordpress-4.9.4-zh_CN.zip + +rm -rf wordpress-4.9.4-zh_CN.zip + +cd /var/www/html/wordpress && mv * ../ + +rm -rf /var/www/html/wordpress/ + +chmod -R 777 /var/www/html/ +``` + +- 修改 Apache 配置文件:`vim /etc/httpd/conf/httpd.conf` + +``` +旧值: +#ServerName www.example.com:80 + +改为: +ServerName www.youmeek.com:80 + +---------------------- + +旧值: +AllowOverride None + +改为: +AllowOverride All + +---------------------- + +旧值: + + DirectoryIndex index.html + + +改为: + + DirectoryIndex index.html index.htm Default.html Default.htm index.php Default.php index.html.var + +``` + +- 重启 Apache + +``` +systemctl restart httpd.service +systemctl enable httpd.service +``` + + +## 创建数据库 + +- SQL 语句:`CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;` + - 如果有数据则直接导入:`/usr/bin/mysql -u root --password=123456 DATABASE_Name < /opt/backup.sql` + +## WordPress 在线配置引导 + +- 浏览器访问: + +## DNS 解析 + +- 我是托管到 DNSPOD,重新指向到新 IP 地址即可 + +## 常用插件 + +- JP Markdown +- WP Code Highlight.js +- FooBox Image Lightbox +- WP Super Cache + +## 常见问题 + +- 安装插件出现:`WordPress需要访问您网页服务器的权限。 请输入您的FTP登录凭据以继续` +- 解决办法:`chown -R apache:apache /var/www/html` + + +## 资料 + +- +- diff --git a/markdown-file/Wormhole-Install-And-Settings.md b/markdown-file/Wormhole-Install-And-Settings.md new file mode 100644 index 00000000..1a7150bb --- /dev/null +++ b/markdown-file/Wormhole-Install-And-Settings.md @@ -0,0 +1,746 @@ +# Wormhole + Flink 最佳实践 + + +## 本文声明 + +- **感谢 Wormhole 的官方帮助!官方微信群很友好,这让我很意外,只能感谢了!** +- 本人大数据和 Ansible 刚看,只会皮毛的皮毛。但是也因为这样的契机促使了我写这篇文章。 +- 因为刚入门,需要了解细节,所以没用 Ambari 这类工具,已经熟悉的可以考虑使用。 +- 希望对你们有帮助。 + +------------------------------------------------------------------- + +## 前置声明 + +- 需要对 Linux 环境,流计算的一些基础概念有基础了解,比如:Source、Sink、YARN、Zookeeper、Kafka、Ansible 等 +- 如果有欠缺,可以查看本系列文章:[点击我](../README.md) + +------------------------------------------------------------------- + +## 本文目标 + +- 统计 **滑动窗口** 下的流过的数据量(count) +- 业务数据格式: + +``` +{ + "id": 1, + "name": "test", + "phone": "18074546423", + "city": "Beijing", + "time": "2017-12-22 10:00:00" +} +``` + +------------------------------------------------------------------- + +## 服务器基础环境设置 + +#### 特别说明 + +- **4 台 8C32G 服务器 CentOS 7.5,内存推荐 16G 或以上。** + - **为了方便,所有服务器都已经关闭防火墙,并且在云服务上设置安全组对外开通所有端口** + - **全程 root 用户** +- 整体部署结构图: + + +![未命名文件(1).png](https://upload-images.jianshu.io/upload_images/12159-7a94673ea075873c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) + + +#### 服务器基础配置 + +- 给对应服务器设置 hostname,方便后面使用: + +``` +hostnamectl --static set-hostname linux01 +hostnamectl --static set-hostname linux02 +hostnamectl --static set-hostname linux03 +hostnamectl --static set-hostname linux04 +``` + +- 给所有服务器设置 hosts:`vim /etc/hosts` + +``` +172.16.0.55 linux01 +172.16.0.92 linux02 +172.16.0.133 linux03 +172.16.0.159 linux04 +``` + +- 在 linux01 生成密钥对,设置 SSH 免密登录 + +``` +生产密钥对 +ssh-keygen -t rsa + + +公钥内容写入 authorized_keys +cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys + +测试: +ssh localhost + +将公钥复制到其他机子 +ssh-copy-id -i ~/.ssh/id_rsa.pub -p 22 root@linux02(根据提示输入 linux02 密码) + +ssh-copy-id -i ~/.ssh/id_rsa.pub -p 22 root@linux03(根据提示输入 linux03 密码) + +ssh-copy-id -i ~/.ssh/id_rsa.pub -p 22 root@linux04(根据提示输入 linux04 密码) + + +在 linux01 上测试 +ssh linux01 + +ssh linux02 + +ssh linux03 + +ssh linux04 +``` + +- 安装基础软件:`yum install -y zip unzip lrzsz git epel-release wget htop deltarpm` +- 安装 Ansible:`yum install -y ansible` +- 配置 Inventory 编辑配置文件:`vim /etc/ansible/hosts` +- 在文件尾部补上如下内容 + +``` +[hadoop-host] +linux01 +linux02 +linux03 + +[kafka-host] +linux04 + +``` + +- 测试 Ansible:`ansible all -a 'ps'`,必须保证能得到如下结果: + +``` +linux01 | CHANGED | rc=0 >> + PID TTY TIME CMD +11088 pts/7 00:00:00 sh +11101 pts/7 00:00:00 python +11102 pts/7 00:00:00 ps + +linux02 | CHANGED | rc=0 >> + PID TTY TIME CMD +10590 pts/1 00:00:00 sh +10603 pts/1 00:00:00 python +10604 pts/1 00:00:00 ps + +linux03 | CHANGED | rc=0 >> + PID TTY TIME CMD +10586 pts/1 00:00:00 sh +10599 pts/1 00:00:00 python +10600 pts/1 00:00:00 ps + +linux04 | CHANGED | rc=0 >> + PID TTY TIME CMD +10574 pts/1 00:00:00 sh +10587 pts/1 00:00:00 python +10588 pts/1 00:00:00 ps +``` + + +#### 服务器基础组件(CentOS 7.x) + + +- 创建脚本文件:`vim /opt/install-basic-playbook.yml` + +``` +- hosts: all + remote_user: root + tasks: + - name: Disable SELinux at next reboot + selinux: + state: disabled + + - name: disable firewalld + command: "{{ item }}" + with_items: + - systemctl stop firewalld + - systemctl disable firewalld + + - name: install-basic + command: "{{ item }}" + with_items: + - yum install -y zip unzip lrzsz git epel-release wget htop deltarpm + + - name: install-vim + shell: "{{ item }}" + with_items: + - yum install -y vim + - curl https://raw.githubusercontent.com/wklken/vim-for-server/master/vimrc > ~/.vimrc + + - name: install-docker + shell: "{{ item }}" + with_items: + - yum install -y yum-utils device-mapper-persistent-data lvm2 + - yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo + - yum makecache fast + - yum install -y docker-ce + - systemctl start docker.service + - docker run hello-world + + - name: install-docker-compose + shell: "{{ item }}" + with_items: + - curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose + - chmod +x /usr/local/bin/docker-compose + - docker-compose --version + - systemctl restart docker.service + - systemctl enable docker.service + +``` + +- 执行命令:`ansible-playbook /opt/install-basic-playbook.yml` + + +------------------------------------------------------------------- + +## Wormhole 所需组件安装 + +- 参考官网: +- 必须组件(版本请不要随便用,而是按照如下说明来): +- 我个人习惯软件都是放在:`/usr/local`,压缩包放在:`/opt` + +#### 关于版本号和端口问题 + +- 百度云打包下载(提取码:8tm3): +- 版本: + - **jdk-8u191-linux-x64.tar.gz** + - **zookeeper-3.4.13(Docker)** + - **kafka_2.11-0.10.2.2.tgz** + - **hadoop-2.6.5.tar.gz** + - **flink-1.5.1-bin-hadoop26-scala_2.11.tgz** + - **spark-2.2.0-bin-hadoop2.6.tgz** + - **mysql-3.7(Docker)** + - **wormhole-0.6.0-beta.tar.gz** +- 端口 + - 都采用组件默认端口 + +#### JDK 安装 + +- 将 linux01 下的 JDK 压缩包复制到所有机子的 /opt 目录下: + +``` +scp -r /opt/jdk-8u191-linux-x64.tar.gz root@linux02:/opt + +scp -r /opt/jdk-8u191-linux-x64.tar.gz root@linux03:/opt + +scp -r /opt/jdk-8u191-linux-x64.tar.gz root@linux04:/opt +``` + +- 在 linux01 创建脚本文件:`vim /opt/jdk8-playbook.yml` + +``` +- hosts: all + remote_user: root + tasks: + - name: copy jdk + copy: src=/opt/jdk-8u191-linux-x64.tar.gz dest=/usr/local + + - name: tar jdk + shell: cd /usr/local && tar zxf jdk-8u191-linux-x64.tar.gz + + - name: set JAVA_HOME + blockinfile: + path: /etc/profile + marker: "#{mark} JDK ENV" + block: | + JAVA_HOME=/usr/local/jdk1.8.0_191 + JRE_HOME=$JAVA_HOME/jre + PATH=$PATH:$JAVA_HOME/bin + CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar + export JAVA_HOME + export JRE_HOME + export PATH + export CLASSPATH + + - name: source profile + shell: source /etc/profile +``` + + +- 执行命令:`ansible-playbook /opt/jdk8-playbook.yml` +- 经过试验,发现还是要自己再手动:`source /etc/profile`,原因未知。 + + +#### Hadoop 集群(HDFS,YARN) + +- Hadoop 集群(HDFS,YARN)(linux01、linux02、linux03):`2.6.5` +- Hadoop 环境可以用脚本文件,剩余部分内容请参考上文手工操作:`vim /opt/hadoop-playbook.yml` + +``` +- hosts: hadoop-host + remote_user: root + tasks: + - name: Creates directory + file: + path: /data/hadoop/hdfs/name + state: directory + - name: Creates directory + file: + path: /data/hadoop/hdfs/data + state: directory + - name: Creates directory + file: + path: /data/hadoop/hdfs/tmp + state: directory + + - name: set HADOOP_HOME + blockinfile: + path: /etc/profile + marker: "#{mark} HADOOP ENV" + block: | + HADOOP_HOME=/usr/local/hadoop + HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop + YARN_CONF_DIR=$HADOOP_HOME/etc/hadoop + PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin + export HADOOP_CONF_DIR + export YARN_CONF_DIR + export HADOOP_HOME + export PATH + + - name: source profile + shell: source /etc/profile +``` + + +- 执行命令:`ansible-playbook /opt/hadoop-playbook.yml` +- 剩余内容较多,具体参考:[点击我](Hadoop-Install-And-Settings.md) + - 解压压缩包:`tar zxvf hadoop-2.6.5.tar.gz` + - 这里最好把目录重命名下:`mv /usr/local/hadoop-2.6.5 /usr/local/hadoop` + - 剩下内容从:修改 linux01 配置,开始阅读 + + +#### Flink + +- 须安装在 linux01 +- Flink 单点(linux01):`1.5.1` +- 拷贝:`cd /usr/local/ && cp /opt/flink-1.5.1-bin-hadoop26-scala_2.11.tgz .` +- 解压:`tar zxf flink-*.tgz` +- 修改目录名:`mv /usr/local/flink-1.5.1 /usr/local/flink` +- 修改配置文件:`vim /usr/local/flink/conf/flink-conf.yaml` + - 在文件最前加上:`env.java.home: /usr/local/jdk1.8.0_191` +- 启动:`cd /usr/local/flink && ./bin/start-cluster.sh` +- 停止:`cd /usr/local/flink && ./bin/stop-cluster.sh` +- 查看日志:`tail -300f log/flink-*-standalonesession-*.log` +- 浏览器访问 WEB 管理:`http://linux01:8081/` +- yarn 启动 + - 先停止下本地模式 + - 测试控制台启动:`cd /usr/local/flink && ./bin/yarn-session.sh -n 2 -jm 2024 -tm 2024` + - 有可能会报:`The Flink Yarn cluster has failed`,可能是资源不够,需要调优内存相关参数 + + +#### Zookeeper + +- Zookeeper 单点(linux04):`3.4.13` +- 单个实例:`docker run -d --restart always --name one-zookeeper -p 2181:2181 -v /etc/localtime:/etc/localtime zookeeper:3.4.13` + +#### Kafka + +- Kafka 单点(linux04):`0.10.2.2` +- 上传压缩包到 /opt 目录下 +- 拷贝压缩包:`cd /usr/local && cp /opt/kafka_2.11-0.10.2.2.tgz .` +- 解压:`tar zxvf kafka_2.11-0.10.2.2.tgz` +- 删除压缩包并重命名目录:`rm -rf kafka_2.11-0.10.2.2.tgz && mv /usr/local/kafka_2.11-0.10.2.2 /usr/local/kafka` +- 修改 kafka-server 的配置文件:`vim /usr/local/kafka/config/server.properties` + +``` +034 行:listeners=PLAINTEXT://0.0.0.0:9092 +039 行:advertised.listeners=PLAINTEXT://linux04:9092 +119 行:zookeeper.connect=linux04:2181 +补充 :auto.create.topics.enable=true +``` + +- 启动 kafka 服务(必须制定配置文件):`cd /usr/local/kafka && bin/kafka-server-start.sh config/server.properties` + - 后台方式运行 kafka 服务:`cd /usr/local/kafka && bin/kafka-server-start.sh -daemon config/server.properties` + - 停止 kafka 服务:`cd /usr/local/kafka && bin/kafka-server-stop.sh` +- 再开一个终端测试: + - 创建 topic 命令:`cd /usr/local/kafka && bin/kafka-topics.sh --create --zookeeper linux04:2181 --replication-factor 1 --partitions 1 --topic my-topic-test` + - 查看 topic 命令:`cd /usr/local/kafka && bin/kafka-topics.sh --list --zookeeper linux04:2181` + - 删除 topic:`cd /usr/local/kafka && bin/kafka-topics.sh --delete --topic my-topic-test --zookeeper linux04:2181` + - 给 topic 发送消息命令:`cd /usr/local/kafka && bin/kafka-console-producer.sh --broker-list linux04:9092 --topic my-topic-test`,然后在出现交互输入框的时候输入你要发送的内容 + - 再开一个终端,进入 kafka 容器,接受消息:`cd /usr/local/kafka && bin/kafka-console-consumer.sh --bootstrap-server linux04:9092 --topic my-topic-test --from-beginning` + - 此时发送的终端输入一个内容回车,接受消息的终端就可以收到。 + +#### MySQL + +- MySQL 单点(linux04):`5.7` +- 创建本地数据存储 + 配置文件目录:`mkdir -p /data/docker/mysql/datadir /data/docker/mysql/conf /data/docker/mysql/log` +- 在宿主机上创建一个配置文件:`vim /data/docker/mysql/conf/mysql-1.cnf`,内容如下: + +``` +[mysql] +default-character-set = utf8 + +[mysqld] +pid-file = /var/run/mysqld/mysqld.pid +socket = /var/run/mysqld/mysqld.sock +datadir = /var/lib/mysql +symbolic-links=0 + +log-error=/var/log/mysql/error.log +default-storage-engine = InnoDB +collation-server = utf8_unicode_ci +init_connect = 'SET NAMES utf8' +character-set-server = utf8 +lower_case_table_names = 1 +max_allowed_packet = 50M +``` + +- 赋权(避免挂载的时候,一些程序需要容器中的用户的特定权限使用):`chmod -R 777 /data/docker/mysql/datadir /data/docker/mysql/log` +- 赋权:`chown -R 0:0 /data/docker/mysql/conf` +- `docker run -p 3306:3306 --name one-mysql -v /data/docker/mysql/datadir:/var/lib/mysql -v /data/docker/mysql/log:/var/log/mysql -v /data/docker/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=aaabbb123456 -d mysql:5.7` +- 连上容器:`docker exec -it one-mysql /bin/bash` + - 连上 MySQL:`mysql -u root -p` + - 创建表:`CREATE DATABASE wormhole DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;` +- **确保用 sqlyog 能直接在外网连上,方便后面调试** + + +#### Spark + +- 须安装在 linux01 +- Spark 单点(linux01):`2.2.0` +- 上传压缩包到 /opt 目录下 +- 拷贝压缩包:`cd /usr/local && cp /opt/spark-2.2.0-bin-hadoop2.6.tgz .` +- 解压:`tar zxvf spark-2.2.0-bin-hadoop2.6.tgz` +- 重命名:`mv /usr/local/spark-2.2.0-bin-hadoop2.6 /usr/local/spark` +- 增加环境变量: + +``` +vim /etc/profile + +SPARK_HOME=/usr/local/spark +PATH=$PATH:${SPARK_HOME}/bin:${SPARK_HOME}/sbin +export SPARK_HOME +export PATH + +source /etc/profile +``` + +- 修改配置:`cp $SPARK_HOME/conf/spark-env.sh.template $SPARK_HOME/conf/spark-env.sh` +- 修改配置:`vim $SPARK_HOME/conf/spark-env.sh` +- 假设我的 hadoop 路径是:/usr/local/hadoop,则最尾巴增加: + +``` +export HADOOP_CONF_DIR=/usr/local/hadoop/etc/hadoop +``` + + +#### 非必须组件 + +- Elasticsearch(支持版本 5.x)(非必须,若无则无法查看 wormhole 处理数据的吞吐和延时) +- Grafana (支持版本 4.x)(非必须,若无则无法查看 wormhole 处理数据的吞吐和延时的图形化展示) + + +------------------------------------------------------------------- + +## Wormhole 安装 + 配置 + +- 须安装在 linux01 +- wormhole 单点(linux01):`0.6.0-beta`,2018-12-06 版本 +- 先在 linux04 机子的 kafka 创建 topic: + +``` +cd /usr/local/kafka && bin/kafka-topics.sh --list --zookeeper linux04:2181 +cd /usr/local/kafka && bin/kafka-topics.sh --create --zookeeper linux04:2181 --replication-factor 1 --partitions 1 --topic source +cd /usr/local/kafka && bin/kafka-topics.sh --create --zookeeper linux04:2181 --replication-factor 1 --partitions 1 --topic wormhole_feedback +cd /usr/local/kafka && bin/kafka-topics.sh --create --zookeeper linux04:2181 --replication-factor 1 --partitions 1 --topic wormhole_heartbeat +``` + +- 上传压缩包到 /opt 目录下 +- 拷贝压缩包:`cd /usr/local && cp /opt/wormhole-0.6.0-beta.tar.gz .` +- 解压:`cd /usr/local && tar -xvf wormhole-0.6.0-beta.tar.gz` +- 修改配置文件:`vim /usr/local/wormhole-0.6.0-beta/conf/application.conf` + +``` + +akka.http.server.request-timeout = 120s + +wormholeServer { + cluster.id = "" #optional global uuid + host = "linux01" + port = 8989 + ui.default.language = "Chinese" + token.timeout = 1 + token.secret.key = "iytr174395lclkb?lgj~8u;[=L:ljg" + admin.username = "admin" #default admin user name + admin.password = "admin" #default admin user password +} + +mysql = { + driver = "slick.driver.MySQLDriver$" + db = { + driver = "com.mysql.jdbc.Driver" + user = "root" + password = "aaabbb123456" + url = "jdbc:mysql://linux04:3306/wormhole?useUnicode=true&characterEncoding=UTF-8&useSSL=false" + numThreads = 4 + minConnections = 4 + maxConnections = 10 + connectionTimeout = 3000 + } +} + +#ldap = { +# enabled = false +# user = "" +# pwd = "" +# url = "" +# dc = "" +# read.timeout = 3000 +# read.timeout = 5000 +# connect = { +# timeout = 5000 +# pool = true +# } +#} + +spark = { + wormholeServer.user = "root" #WormholeServer linux user + wormholeServer.ssh.port = 22 #ssh port, please set WormholeServer linux user can password-less login itself remote + spark.home = "/usr/local/spark" + yarn.queue.name = "default" #WormholeServer submit spark streaming/job queue + wormhole.hdfs.root.path = "hdfs://linux01/wormhole" #WormholeServer hdfslog data default hdfs root path + yarn.rm1.http.url = "linux01:8088" #Yarn ActiveResourceManager address + yarn.rm2.http.url = "linux01:8088" #Yarn StandbyResourceManager address +} + +flink = { + home = "/usr/local/flink" + yarn.queue.name = "default" + feedback.state.count=100 + checkpoint.enable=false + checkpoint.interval=60000 + stateBackend="hdfs://linux01/flink-checkpoints" + feedback.interval=30 +} + +zookeeper = { + connection.url = "linux04:2181" #WormholeServer stream and flow interaction channel + wormhole.root.path = "/wormhole" #zookeeper +} + +kafka = { + brokers.url = "linux04:9092" + zookeeper.url = "linux04:2181" + topic.refactor = 1 + using.cluster.suffix = false #if true, _${cluster.id} will be concatenated to consumer.feedback.topic + consumer = { + feedback.topic = "wormhole_feedback" + poll-interval = 20ms + poll-timeout = 1s + stop-timeout = 30s + close-timeout = 20s + commit-timeout = 70s + wakeup-timeout = 60s + max-wakeups = 10 + session.timeout.ms = 60000 + heartbeat.interval.ms = 50000 + max.poll.records = 1000 + request.timeout.ms = 80000 + max.partition.fetch.bytes = 10485760 + } +} + +#kerberos = { +# keyTab="" #the keyTab will be used on yarn +# spark.principal="" #the principal of spark +# spark.keyTab="" #the keyTab of spark +# server.config="" #the path of krb5.conf +# jaas.startShell.config="" #the path of jaas config file which should be used by start.sh +# jaas.yarn.config="" #the path of jaas config file which will be uploaded to yarn +# server.enabled=false #enable wormhole connect to Kerberized cluster +#} + +# choose monitor method among ES、MYSQL +monitor ={ + database.type="MYSQL" +} + +#Wormhole feedback data store, if doesn't want to config, you will not see wormhole processing delay and throughput +#if not set, please comment it + +#elasticSearch.http = { +# url = "http://localhost:9200" +# user = "" +# password = "" +#} + +#display wormhole processing delay and throughput data, get admin user token from grafana +#garfana should set to be anonymous login, so you can access the dashboard through wormhole directly +#if not set, please comment it + +#grafana = { +# url = "http://localhost:3000" +# admin.token = "jihefouglokoj" +#} + +#delete feedback history data on time +maintenance = { + mysql.feedback.remain.maxDays = 7 + elasticSearch.feedback.remain.maxDays = 7 +} + + +#Dbus integration, support serveral DBus services, if not set, please comment it + +#dbus = { +# api = [ +# { +# login = { +# url = "http://localhost:8080/keeper/login" +# email = "" +# password = "" +# } +# synchronization.namespace.url = "http://localhost:8080/keeper/tables/riderSearch" +# } +# ] +#} +``` + +- 初始化表结构脚本路径: + - 该脚本存在一个问题:初始化脚本和补丁脚本混在一起,所以直接复制执行会有报错,但是报错的部分是不影响 + - 我是直接把基础 sql 和补丁 sql 分开执行,方便判断。 +- 启动:`sh /usr/local/wormhole-0.6.0-beta/bin/start.sh` +- 查看 log:`tail -200f /usr/local/wormhole-0.6.0-beta/logs/application.log` +- 部署完成,浏览器访问: +- 默认管理员用户名:admin,密码:admin + +------------------------------------------------------------------- + +## 创建用户 + +- **参考官网,必须先了解下**: +- 必须创建用户,后面才能进入 Project 里面创建 Stream / Flow +- 创建的用户类型必须是:`user` +- 假设这里创建的用户叫做:`user1@bg.com` + +------------------------------------------------------------------- + +## 创建 Source 需要涉及的概念 + +#### 创建 Instance + +- Instance 用于绑定各个组件的所在服务连接 +- 一般我们都会选择 Kafka 作为 source,后面的基础也是基于 Kafka 作为 Source 的场景 +- 假设填写实例名:`source_kafka` +- URL:`linux04:9092` + +#### 创建 Database + +- 各个组件的具体数据库、Topic 等信息 +- 假设填写 Topic Name:`source` +- Partition:1 + +#### 创建 Namespace + +- wormhole 抽象出来的概念 +- 用于数据分类 +- 假设填写 Tables:`ums_extension id` +- 配置 schema,记得配置上 ums_ts + +``` +{ + "id": 1, + "name": "test", + "phone": "18074546423", + "city": "Beijing", + "time": "2017-12-22 10:00:00" +} +``` + + +------------------------------------------------------------------- + +## 创建 Sink 需要涉及的概念 + +#### 创建 Instance + +- 假设填写实例名:`sink_mysql` +- URL:`linux04:3306` + +#### 创建 Database + +- 假设填写 Database Name:`sink` +- config 参数:`useUnicode=true&characterEncoding=UTF-8&useSSL=false&rewriteBatchedStatements=true` + + + +#### 创建 Namespace + +- 假设填写 Tables: `user id` + + +------------------------------------------------------------------- + +## 创建 Project + +- 项目标识:`demo` + +------------------------------------------------------------------- + + +## Flink Stream + +- Stream 是在 Project 内容页下才能创建 +- 一个 Stream 可以有多个 Flow +- 并且是 Project 下面的用户才能创建,admin 用户没有权限 +- 要删除 Project 必须先进入 Project 内容页删除所有 Stream 之后 admin 才能删除 Project +- 新建 Stream + - Stream type 类型选择:`Flink` + - 假设填写 Name:`wormhole_stream_test` + +## Flink Flow + +- 假设 Flow name 为:`wormhole_flow_test` +- Flow 是在 Project 内容页下才能创建 +- 并且是 Project 下面的用户才能创建,admin 用户没有权限 +- Flow 会关联 source 和 sink +- 要删除 Project 必须先进入 Project 内容页删除所有 Stream 之后 admin 才能删除 Project +- 基于 Stream 新建 Flow + - Pipeline + - Transformation + - + - NO_SKIP 滑动窗口 + - SKIP_PAST_LAST_EVENT 滚动窗口 + - KeyBy 分组字段 + - Output + - Agg:将匹配的多条数据做聚合,生成一条数据输出,例:field1:avg,field2:max(目前支持 max/min/avg/sum) + - Detail:将匹配的多条数据逐一输出 + - FilteredRow:按条件选择指定的一条数据输出,例:head/last/ field1:min/max + - Confirmation +- 注意:Stream 处于 running 状态时,才可以启动 Flow + + +------------------------------------------------------------------- + +## Kafka 发送测试数据 + +- 在 linux04 机子上 +- `cd /usr/local/kafka/bin && ./kafka-console-producer.sh --broker-list linux04:9092 --topic source --property "parse.key=true" --property "key.separator=@@@"` +- 发送 UMS 流消息协议规范格式: + +``` +data_increment_data.kafka.source_kafka.source.ums_extension.*.*.*@@@{"id": 1, "name": "test1", "phone":"18074546423", "city": "Beijing", "time": "2017-12-22 10:01:00"} + +data_increment_data.kafka.source_kafka.source.ums_extension.*.*.*@@@{"id": 2, "name": "test2", "phone":"18074546423", "city": "Beijing", "time": "2017-12-22 10:02:00"} + +data_increment_data.kafka.source_kafka.source.ums_extension.*.*.*@@@{"id": 3, "name": "test3", "phone":"18074546423", "city": "Beijing", "time": "2017-12-22 10:03:00"} + +data_increment_data.kafka.source_kafka.source.ums_extension.*.*.*@@@{"id": 4, "name": "test4", "phone":"18074546423", "city": "Beijing", "time": "2017-12-22 10:04:00"} + +data_increment_data.kafka.source_kafka.source.ums_extension.*.*.*@@@{"id": 5, "name": "test5", "phone":"18074546423", "city": "Beijing", "time": "2017-12-22 10:05:00"} + +data_increment_data.kafka.source_kafka.source.ums_extension.*.*.*@@@{"id": 6, "name": "test6", "phone":"18074546423", "city": "Beijing", "time": "2017-12-22 10:06:00"} + +data_increment_data.kafka.source_kafka.source.ums_extension.*.*.*@@@{"id": 7, "name": "test7", "phone":"18074546423", "city": "Beijing", "time": "2017-12-22 10:07:00"} + +data_increment_data.kafka.source_kafka.source.ums_extension.*.*.*@@@{"id": 8, "name": "test8", "phone":"18074546423", "city": "Beijing", "time": "2017-12-22 10:08:00"} + +data_increment_data.kafka.source_kafka.source.ums_extension.*.*.*@@@{"id": 9, "name": "test9", "phone":"18074546423", "city": "Beijing", "time": "2017-12-22 10:09:00"} +``` + diff --git a/markdown-file/YApi-Install-And-Settings.md b/markdown-file/YApi-Install-And-Settings.md new file mode 100644 index 00000000..43899d6f --- /dev/null +++ b/markdown-file/YApi-Install-And-Settings.md @@ -0,0 +1,30 @@ +# YApi 安装和配置 + + +## 部署的环境 + +- 系统:`CentOS 7.4` +- 硬件要求:`1 GB RAM minimum` +- ip:`http://192.168.1.121` +- docker version:`17.12.1-ce, build 7390fc6` +- docker-compose version:`1.18.0, build 8dd22a9` + +> 建议部署成 http 站点,因 chrome 浏览器安全限制,部署成 https 会导致测试功能在请求 http 站点时文件上传功能异常。--[来源](https://yapi.ymfe.org/devops.html) + +## Docker 快速部署 + +- 一个好心人的维护: +- 使用方法: + - work path:`mkdir -p /opt/git-data` + - clone:`cd /opt/git-data && git clone https://github.com/branchzero/yapi-docker.git` + - permission:`chmod -R 777 /opt/git-data` + - run command:`cd /opt/git-data/yapi-docker && docker-compose up -d` + - open chrome:`http://192.168.1.121:3000` +- 初始化管理员账号名:`admin@admin.com`,密码:`ymfe.org` + +## YApi 介绍 + +- 官网: +- Github: +- 官网在线演示: +- 使用手册: diff --git a/markdown-file/Zabbix-Install-And-Settings.md b/markdown-file/Zabbix-Install-And-Settings.md new file mode 100644 index 00000000..7eeca22a --- /dev/null +++ b/markdown-file/Zabbix-Install-And-Settings.md @@ -0,0 +1,26 @@ +# Zabbix 安装和配置 + + +## Zabbix 说明 + +- Zabbix 是一个企业级的分布式开源监控方案,也是目前 Linux 最主流的监控方案。 +- Zabbix 官网: +- Zabbix 官网的中文文档: + +## Zabbix 基础概念 + +- zabbix-agent +- zabbix-server +- 数据库(mysql/PostgreSQL) +- web 界面管理 +- 主机(host),一般就是安装 zabbix-agent 服务服务器的称呼。一般配置 Zabbix 中 host name 就填写你的服务器的 `hostname` 命令展示出来的结果值 +- 主机组(host groups) + +## Zabbix 安装 + +- 官网下载最新稳定版本 **3.4** +- Zabbix 官网下载和安装说明: + + + +## 资料 diff --git a/markdown-file/Zookeeper-Install.md b/markdown-file/Zookeeper-Install.md new file mode 100644 index 00000000..5d3b3572 --- /dev/null +++ b/markdown-file/Zookeeper-Install.md @@ -0,0 +1,268 @@ +# Zookeeper 安装 + + +## Docker 部署 Zookeeper + + +#### 单个实例 + +- 官网仓库: +- 单个实例:`docker run -d --restart always --name one-zookeeper -p 2181:2181 -v /etc/localtime:/etc/localtime zookeeper:latest` + - 默认端口暴露是:`This image includes EXPOSE 2181 2888 3888 (the zookeeper client port, follower port, election port respectively)` +- 容器中的几个重要目录(有需要挂载的可以指定): + - `/data` + - `/datalog` + - `/conf` + + +#### 单机多个实例(集群) + +- 创建 docker compose 文件:`vim zookeeper.yml` +- 下面内容来自官网仓库: + +``` +version: '3.1' + +services: + zoo1: + image: zookeeper + restart: always + hostname: zoo1 + ports: + - 2181:2181 + environment: + ZOO_MY_ID: 1 + ZOO_SERVERS: server.1=0.0.0.0:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888 + + zoo2: + image: zookeeper + restart: always + hostname: zoo2 + ports: + - 2182:2181 + environment: + ZOO_MY_ID: 2 + ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=0.0.0.0:2888:3888 server.3=zoo3:2888:3888 + + zoo3: + image: zookeeper + restart: always + hostname: zoo3 + ports: + - 2183:2181 + environment: + ZOO_MY_ID: 3 + ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=0.0.0.0:2888:3888 +``` + +- 启动:`docker-compose -f zookeeper.yml -p zk_test up -d` + - 参数 -p zk_test 表示这个 compose project 的名字,等价于:`COMPOSE_PROJECT_NAME=zk_test docker-compose -f zookeeper.yml up -d` + - 不指定项目名称,Docker-Compose 默认以当前文件目录名作为应用的项目名 + - 报错是正常情况的。 +- 停止:`docker-compose -f zookeeper.yml -p zk_test stop` + +#### 先安装 nc 再来校验 zookeeper 集群情况 + +- 环境:CentOS 7.4 +- 官网下载:,找到 rpm 包 +- 当前时间(201803)最新版本下载:`wget https://nmap.org/dist/ncat-7.60-1.x86_64.rpm` +- 安装:`sudo rpm -i ncat-7.60-1.x86_64.rpm` +- ln 下:`sudo ln -s /usr/bin/ncat /usr/bin/nc` +- 检验:`nc --version` + +#### 校验 + +- 命令:`echo stat | nc 127.0.0.1 2181`,得到如下信息: + +``` +Zookeeper version: 3.4.11-37e277162d567b55a07d1755f0b31c32e93c01a0, built on 11/01/2017 18:06 GMT +Clients: + /172.21.0.1:58872[0](queued=0,recved=1,sent=0) + +Latency min/avg/max: 0/0/0 +Received: 1 +Sent: 0 +Connections: 1 +Outstanding: 0 +Zxid: 0x100000000 +Mode: follower +Node count: 4 +``` + +- 命令:`echo stat | nc 127.0.0.1 2182`,得到如下信息: + +``` +Zookeeper version: 3.4.11-37e277162d567b55a07d1755f0b31c32e93c01a0, built on 11/01/2017 18:06 GMT +Clients: + /172.21.0.1:36190[0](queued=0,recved=1,sent=0) + +Latency min/avg/max: 0/0/0 +Received: 1 +Sent: 0 +Connections: 1 +Outstanding: 0 +Zxid: 0x500000000 +Mode: follower +Node count: 4 +``` + + +- 命令:`echo stat | nc 127.0.0.1 2183`,得到如下信息: + +``` +Zookeeper version: 3.4.11-37e277162d567b55a07d1755f0b31c32e93c01a0, built on 11/01/2017 18:06 GMT +Clients: + /172.21.0.1:33344[0](queued=0,recved=1,sent=0) + +Latency min/avg/max: 0/0/0 +Received: 1 +Sent: 0 +Connections: 1 +Outstanding: 0 +Zxid: 0x500000000 +Mode: leader +Node count: 4 +``` + +#### 多机多个实例(集群) + +- 三台机子: + - 内网 ip:`172.24.165.129`,外网 ip:`47.91.22.116` + - 内网 ip:`172.24.165.130`,外网 ip:`47.91.22.124` + - 内网 ip:`172.24.165.131`,外网 ip:`47.74.6.138` +- 修改三台机子 hostname: + - 节点 1:`hostnamectl --static set-hostname youmeekhost1` + - 节点 2:`hostnamectl --static set-hostname youmeekhost2` + - 节点 3:`hostnamectl --static set-hostname youmeekhost3` +- 三台机子的 hosts 都修改为如下内容:`vim /etc/hosts` + +``` +172.24.165.129 youmeekhost1 +172.24.165.130 youmeekhost2 +172.24.165.131 youmeekhost3 +``` + +- 节点 1: + +``` +docker run -d \ +-v /data/docker/zookeeper/data:/data \ +-v /data/docker/zookeeper/log:/datalog \ +-e ZOO_MY_ID=1 \ +-e "ZOO_SERVERS=server.1=youmeekhost1:2888:3888 server.2=youmeekhost2:2888:3888 server.3=youmeekhost3:2888:3888" \ +--name=zookeeper1 --net=host --restart=always zookeeper +``` + + +- 节点 2: + +``` +docker run -d \ +-v /data/docker/zookeeper/data:/data \ +-v /data/docker/zookeeper/log:/datalog \ +-e ZOO_MY_ID=2 \ +-e "ZOO_SERVERS=server.1=youmeekhost1:2888:3888 server.2=youmeekhost2:2888:3888 server.3=youmeekhost3:2888:3888" \ +--name=zookeeper2 --net=host --restart=always zookeeper +``` + + +- 节点 3: + +``` +docker run -d \ +-v /data/docker/zookeeper/data:/data \ +-v /data/docker/zookeeper/log:/datalog \ +-e ZOO_MY_ID=3 \ +-e "ZOO_SERVERS=server.1=youmeekhost1:2888:3888 server.2=youmeekhost2:2888:3888 server.3=youmeekhost3:2888:3888" \ +--name=zookeeper3 --net=host --restart=always zookeeper +``` + + + + +## 需要环境 + +- JDK 安装 + +## 下载安装 + +- 官网: +- 此时(201702)最新稳定版本:Release `3.4.9` +- 官网下载: +- 我这里以:`zookeeper-3.4.8.tar.gz` 为例 +- 安装过程: + - `mkdir -p /usr/program/zookeeper/data` + - `cd /opt/setups` + - `tar zxvf zookeeper-3.4.8.tar.gz` + - `mv /opt/setups/zookeeper-3.4.8 /usr/program/zookeeper` + - `cd /usr/program/zookeeper/zookeeper-3.4.8/conf` + - `mv zoo_sample.cfg zoo.cfg` + - `vim zoo.cfg` +- 将配置文件中的这个值: + - 原值:`dataDir=/tmp/zookeeper` + - 改为:`dataDir=/usr/program/zookeeper/data` +- 防火墙开放2181端口 + - `iptables -A INPUT -p tcp -m tcp --dport 2181 -j ACCEPT` + - `service iptables save` + - `service iptables restart` +- 启动 zookeeper:`sh /usr/program/zookeeper/zookeeper-3.4.8/bin/zkServer.sh start` +- 停止 zookeeper:`sh /usr/program/zookeeper/zookeeper-3.4.8/bin/zkServer.sh stop` +- 查看 zookeeper 状态:`sh /usr/program/zookeeper/zookeeper-3.4.8/bin/zkServer.sh status` + - 如果是集群环境,下面几种角色 + - leader + - follower + +## 集群环境搭建 + +### 确定机子环境 + +- 集群环境最少节点是:3,且节点数必须是奇数,生产环境推荐是:5 个机子节点。 +- 系统都是 CentOS 6 +- 机子 1:192.168.1.121 +- 机子 2:192.168.1.111 +- 机子 3:192.168.1.112 + +### 配置 + +- 在三台机子上都做如上文的流程安装,再补充修改配置文件:`vim /usr/program/zookeeper/zookeeper-3.4.8/conf/zoo.cfg` +- 三台机子都增加下面内容: + +``` nginx +server.1=192.168.1.121:2888:3888 +server.2=192.168.1.111:2888:3888 +server.3=192.168.1.112:2888:3888 +``` + +- 在 机子 1 增加一个该文件:`vim /usr/program/zookeeper/data/myid`,文件内容填写:`1` +- 在 机子 2 增加一个该文件:`vim /usr/program/zookeeper/data/myid`,文件内容填写:`2` +- 在 机子 3 增加一个该文件:`vim /usr/program/zookeeper/data/myid`,文件内容填写:`3` +- 然后在三台机子上都启动 zookeeper:`sh /usr/program/zookeeper/zookeeper-3.4.8/bin/zkServer.sh start` +- 分别查看三台机子的状态:`sh /usr/program/zookeeper/zookeeper-3.4.8/bin/zkServer.sh status`,应该会得到类似这样的结果: + +``` +Using config: /usr/program/zookeeper/zookeeper-3.4.8/bin/../conf/zoo.cfg +Mode: follower 或者 Mode: leader +``` + +## Zookeeper 客户端工具 + +#### ZooInspector + +- 下载地址: +- 解压,双击 jar 文件,效果如下: +- ![ZooInspector](../images/Zookeeper-Client-ZooInspector.png) + +#### zooweb + +- 下载地址: +- Spring Boot 的 Web 项目,直接:`java -jar zooweb-1.0.jar` 启动 web 服务,然后访问: +- ![zooweb](../images/Zookeeper-Client-zooweb.png) + + + + + + +## 资料 + +- \ No newline at end of file diff --git a/Zsh.md b/markdown-file/Zsh.md similarity index 83% rename from Zsh.md rename to markdown-file/Zsh.md index 5ba48a8f..e0e294a3 100644 --- a/Zsh.md +++ b/markdown-file/Zsh.md @@ -37,15 +37,15 @@ - oh-my-zsh 帮我们整理了一些常用的 Zsh 扩展功能和主题: - 我们无需自己去捣搞 Zsh,直接用 oh-my-zsh 就足够了,如果你想继续深造的话那再去弄。 - 先安装 git:`sudo yum install -y git` -- 安装 oh-my-zsh(这个过程可能会有点慢,或者需要重试几次):`wget https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O - | sh` +- 安装 oh-my-zsh(这个过程可能会有点慢,或者需要重试几次):`wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O - | sh` - 整个过程效果如下图: - - ![oh-my-zsh 安装](images/Zsh-a-1.jpg) + - ![oh-my-zsh 安装](../images/Zsh-a-1.jpg) - 在以 root 用户为前提下,oh-my-zsh 的安装目录:**/root/.oh-my-zsh** - 在以 root 用户为前提下,Zsh 的配置文件位置:**/root/.zshrc** - 为 root 用户设置 zsh 为系统默认 shell:`chsh -s /bin/zsh root` - 如果你要重新恢复到 bash:`chsh -s /bin/bash root` - 现在你关掉终端或是重新连上 shell,现在开头是一个箭头了,如下图: - - ![oh-my-zsh 安装](images/Zsh-b-1.jpg) + - ![oh-my-zsh 安装](../images/Zsh-b-1.jpg) ## Home / End 失灵问题 @@ -62,8 +62,20 @@ - oh-my-zsh 的插件列表介绍(太长了,用源码不精准地统计下有 149 个): - 我们看下安装 oh-my-zsh 的时候自带有多少个插件:`ls -l /root/.oh-my-zsh/plugins |grep "^d"|wc -l`,我这边得到的结果是:211 - 编辑配置文件:`vim /root/.zshrc`,找到下图的地方,怎么安装,原作者注释写得很清楚了,别装太多了,默认 git 是安装的。 - - ![oh-my-zsh 安装](images/Zsh-c-1.jpg) + - ![oh-my-zsh 安装](../images/Zsh-c-1.jpg) - 插件推荐: + - `zsh-autosuggestions` + - 这个插件会对历史命令一些补全,类似 fish 终端 + - 插件官网: + - 安装,复制该命令:`git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions` + - 编辑:`vim ~/.zshrc`,找到这一行,后括号里面的后面添加:`plugins=( 前面的一些插件名称,换行,加上:zsh-autosuggestions)` + - 刷新下配置:`source ~/.zshrc` + - `zsh-syntax-highlighting` + - 这个插件会对终端命令高亮显示,比如正确的拼写会是绿色标识,否则是红色,另外对于一些shell输出语句也会有高亮显示,算是不错的辅助插件 + - 插件官网: + - 安装,复制该命令:`git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting` + - 编辑:`vim ~/.zshrc`,找到这一行,后括号里面的后面添加:`plugins=( 前面的一些插件名称,换行,加上:zsh-syntax-highlighting)` + - 刷新下配置:`source ~/.zshrc` - `wd` - 简单地讲就是给指定目录映射一个全局的名字,以后方便直接跳转到这个目录,比如: - 编辑配置文件,添加上 wd 的名字:`vim /root/.zshrc` @@ -80,12 +92,6 @@ - 进入解压后目录并安装:`cd autojump_v21.1.2/ ; ./install.sh` - 再执行下这个:`source /etc/profile.d/autojump.sh` - 编辑配置文件,添加上 autojump 的名字:`vim /root/.zshrc` - - `zsh-syntax-highlighting` - - 这个插件会对终端命令高亮显示,比如正确的拼写会是绿色标识,否则是红色,另外对于一些shell输出语句也会有高亮显示,算是不错的辅助插件 - - 插件官网: - - 安装,复制该命令:'git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting' - - 编辑:`vim ~/.zshrc`,找到这一行,后括号里面的后面添加:`plugins=( 前面的一些插件名称 zsh-syntax-highlighting)` - - 刷新下配置:`source ~/.zshrc` ### 主题 @@ -99,7 +105,7 @@ - `avit` - `blinks` - 编辑配置文件:`vim /root/.zshrc`,找到下图的地方,怎么安装,原作者注释写得很清楚了,如果你没特别的喜欢那就选择随机吧。 - - ![oh-my-zsh 安装](images/Zsh-d-1.jpg) + - ![oh-my-zsh 安装](../images/Zsh-d-1.jpg) - 配置好新主题需要重新连接 shell 才能看到效果 diff --git a/markdown-file/kali-linux-settings/kali-linux-basic-settings.md b/markdown-file/kali-linux-settings/kali-linux-basic-settings.md new file mode 100644 index 00000000..d3dc1404 --- /dev/null +++ b/markdown-file/kali-linux-settings/kali-linux-basic-settings.md @@ -0,0 +1,119 @@ +# 基础设置 + + +## 修改源 + +- 编辑配置文件:`vim /etc/apt/sources.list` +- 在文件 **最前面** 添加以下条目,官网文档: + +``` +#中科大的源 +deb https://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib +deb-src https://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib +``` + +- `apt-get update` 更新索引 + +## 安装公共工具 + +- `apt-get install -y zip unzip lrzsz git` + + +## 安装 Zsh、Vim + +``` +apt-get install -y zsh + +wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O - | sh + +chsh -s /bin/zsh root + +apt-get install -y vim + +curl https://raw.githubusercontent.com/wklken/vim-for-server/master/vimrc > ~/.vimrc +``` + +## 安装搜狗输入法 + +- 下载 deb 文件: +- 安装依赖:`apt-get install -y fcitx` +- 安装 deb 文件:`dpkg -i 文件名` + - 应该会提示有部分依赖不存在,则执行:`apt-get --fix-broken install -y` +- 安装完成后: + - 终端输入:`im-config`,一路确定,在有一个提示选项中选择:`fcitx`,重启电脑,按 Ctrl + Space 就可以切换输入法 + +## 安装 Visual Studio Code + +- 下载 deb 文件: +- 安装 deb 文件:`dpkg -i 文件名` + - 应该会提示有部分依赖不存在,则执行:`apt-get --fix-broken install -y` +- 安装扩展 + - 扩展仓库: + - 中文语言包 + - Markdown + - GitLens + - REST Client + - Atom One Dark Theme + +## 安装剪切板 + +- 命令:`sudo apt-get install parcellite` + - 修改快捷键:`右键软件 | 首选项 | Hotkeys | 历史记录按键组合` + +## 安装 Peek(Gif 录制) + +- 自己构建 deb 包安装 + +``` +sudo apt install cmake valac libgtk-3-dev libkeybinder-3.0-dev libxml2-utils gettext txt2man + +git clone https://github.com/phw/peek.git --depth=1 +mkdir peek/build +cd peek/build +cmake -DCMAKE_INSTALL_PREFIX=/usr -DGSETTINGS_COMPILE=OFF .. +make package + +sudo dpkg -i peek-*-Linux.deb +``` + +## 安装截图软 + +``` +wget http://packages.linuxdeepin.com/deepin/pool/main/d/deepin-scrot/deepin-scrot_2.0-0deepin_all.deb +sudo dpkg -i deepin-scrot_2.0-0deepin_all.deb + +apt-get --fix-broken install -y + +//终端下启动 +deepin-scrot +``` + +- 配置快捷键来截图方法(思路一样): + - Kali 的快捷键设置在:设置 - 设备 - Keyboard 下 + + +## 升级 firefox + +- 官网下载: +- 假设放在 /opt 目录下,进行解压:`tar xjf firefox-*.tar.bz2` +- 进入图标存放目录|:`cd /usr/share/applications` +- 创建文件并编辑:`sudo vim firefoxnew.desktop` + +``` ini +[Desktop Entry] +Name=firefoxnew +Name[zh_CN]=firefoxnew +Comment=firefox new +Exec=/opt/firefox/firefox +Icon=/opt/firefox/icons/updater.png +Terminal=false +Type=Application +Categories=Application; +Encoding=UTF-8 +StartupNotify=true +``` + + +## 安装 SSR 客户端 + +- 查看: diff --git a/markdown-file/kali-linux-settings/kali-linux-install.md b/markdown-file/kali-linux-settings/kali-linux-install.md new file mode 100644 index 00000000..f8fa9f83 --- /dev/null +++ b/markdown-file/kali-linux-settings/kali-linux-install.md @@ -0,0 +1,28 @@ +# Kali Linux 安装 + + +## 制作 U 盘 + + +- 准备一个 U 盘,下载这个软件:[USBWriter(提取码:5aa2)](https://pan.baidu.com/s/1gg83h9T) +- USBWriter 的使用很简单,如下图即可制作一个 CentOS 系统盘 + +![VMware 下安装](../../images/CentOS-7-Install-a-0.jpg) + + +## 安装过程 + +- 这几年的几个版本安装过程都是类似的,大家可以参考这个视频教程: + - + - 其中,安装第一步选择中文,安装完成就会是中文的,不需要像上面这个视频那么麻烦。 +- 安装过程,比较差的机子差不多要 20 ~ 30 分钟。 +- 比较重点的几个步骤推荐: + - `使用整个磁盘` + - `将所有文件放在同一个分区中` + - `分区设定结束并修改写入磁盘` + - `将改动写入磁盘 -- 是` + - `使用网络镜像 -- 是` + +## 软件及系统升级 + +- `apt-get update && apt-get upgrade` \ No newline at end of file diff --git a/markdown-file/kali-linux-settings/kali-linux-penetration-test.md b/markdown-file/kali-linux-settings/kali-linux-penetration-test.md new file mode 100644 index 00000000..58751c06 --- /dev/null +++ b/markdown-file/kali-linux-settings/kali-linux-penetration-test.md @@ -0,0 +1,61 @@ +# 渗透测试思路 + +- 来源:《Kali Linux 渗透测试的艺术》 + +## 范围界定 + +- 收集需求 +- 筹划工作 +- 边界分析 +- 明确业务指标 +- 项目管理和统筹调度 + +## 信息收集 + +- 互联网上的公开信息 +- 域名注册信息(whois) +- DNS 记录分析 +- 路由信息 +- 利用搜索引擎搜索目标历史记录 + - Google Hack,根据 Google 的 `inurl` 等高级用法查询一些系统可能存在风险 + - 比如查找链接是:`asp?id=`、`php?id=1` 的链接。asp 和 php 的系统相对比较薄弱。特别是对于 asp 的老系统,建议开发者还是放弃。 + +## 目标识别 + +- 识别目标还在线的主机 +- 识别目标在线主机的系统 + +## 服务枚举 + +- 获取目标主机的情况 + - 开放的端口 + - 操作系统 + - 网络服务 + +## 漏洞扫描 + +- 根据种类划分 + - 本地漏洞 + - 远程漏洞 +- 根据类型划分 + - 设计类漏洞 + - 实施类漏洞 + - 运营类漏洞 + +## 漏洞利用 + + +## 社会工程学攻击 + +- 心理学建模 +- 社会关系 + +## 提升权限 + +## 密码攻击 + +## 无线网络渗透测试 + +## 访问维护 + +- 创建后门 diff --git a/markdown-file/kali-linux-settings/kali-linux-social-engineering.md b/markdown-file/kali-linux-settings/kali-linux-social-engineering.md new file mode 100644 index 00000000..7432bd85 --- /dev/null +++ b/markdown-file/kali-linux-settings/kali-linux-social-engineering.md @@ -0,0 +1,23 @@ +# 社会工程学 + +## 简介 + + + +## SET 工具 + +- 命令:`setoolkit`(命令行向导式交互) +- 选择 1:`Social-Engineering Attacks`,结果如下: + +``` +1) Spear-Phishing Attack Vectors #鱼叉式钓鱼攻击向量(也称针对性钓鱼攻击) +2) Website Attack Vectors #网页攻击向量 +3) Infectious Media Generator #媒介感染生成器 +4) Create a Payload and Listener #生成一个payload和监听 +5) Mass Mailer Attack #大规模邮件钓鱼 +6) Arduino-Based Attack Vector #基于Arduino的攻击(类似于单片机) +7) Wireless Access Point Attack Vector #无线接入点攻击 +8) QRCode Generator Attack Vector #二维码攻击 +9) Powershell Attack Vectors #powershell攻击 +10) Third Party Modules #第三方模块 +``` diff --git a/markdown-file/kali-linux-settings/kali-linux-sql-injection.md b/markdown-file/kali-linux-settings/kali-linux-sql-injection.md new file mode 100644 index 00000000..e8d7815a --- /dev/null +++ b/markdown-file/kali-linux-settings/kali-linux-sql-injection.md @@ -0,0 +1,105 @@ +# SQL 注入 + +## 探测到底是不是通过拼接字符串方式使用 SQL + +- 常用字符: + +``` +' +" +' and 1=1 +' and 1=2 +1 or 1=1 +1' or '1'='1 +1" or "1"="1 +1' order by 1-- +union select 1,2-- +@@version +@@datadir +user() +database() +information_schema.tables + +``` + + +## sqlmap 分析数据库和表名、dump 表数据 + +#### sqlmap 介绍 + +- 目前做 SQL 注入的工具一般大家都是选择:[sqlmap](http://sqlmap.org/) + - 目前(2018年08月)只支持:2.6.x 和 2.7.x +- 支持的 5 种注入类型: + - 基于布尔的盲注,即可以根据返回页面判断条件真假的注入。 + - 基于时间的盲注,即不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断。 + - 基于报错注入,即页面会返回错误信息,或者把注入的语句的结果直接返回在页面中。 + - 联合查询注入,可以使用union的情况下的注入。 + - 堆查询注入,可以同时执行多条语句的执行时的注入。 + + +#### sqlmap 使用 + +- sqlmap 的输出信息按从简到繁共分为7个级别,依次为 0 ~ 6,级别越高,检测越全面。分别代表: + - 使用参数 `-v <级别>` 来指定某个等级,默认输出级别为 1 + +``` +0:只显示 Python 的 tracebacks 信息、错误信息 [ERROR] 和关键信息 [CRITICAL]; +1:同时显示普通信息 [INFO] 和警告信息[WARNING]; +2:同时显示调试信息[DEBUG]; +3:同时显示注入使用的攻击荷载; +4:同时显示 HTTP 请求; +5:同时显示 HTTP 响应头; +6:同时显示 HTTP 响应体。 +``` + +- 将 Google 搜索前一百个结果作为攻击目标:`sqlmap -g "inurl:\".asp?id=1\""` +- 检查注入点(GET):`sqlmap -u 目标网址` +- 检查注入点(POST 数据,多个数据用分号隔开):`sqlmap -u 目标网址 --data="id=0;name=werner" --param-del=";"` +- 检查注入点(Cookie,等级必须是 2 以上):`sqlmap -u 目标网址 --cookie –level 2 "JSESSIONID=123456;NAME=youmeek;" --cookie-del=";"` +- 获取所有数据库信息:`sqlmap -u 目标网址 --dbs` +- 获取所有数据库用户:`sqlmap -u 目标网址 --users` +- 获取当前数据库信息:`sqlmap -u 目标网址 --current-db` +- 获取当前用户:`sqlmap -u 目标网址 --current-user` +- 获取当前数据库和当前用户:`sqlmap -u 目标网址 --current-db --current-user` +- 获取有几张表:`sqlmap -u 目标网址 --tables` +- 获取指定表的字段有哪些:`sqlmap -u 目标网址 -T 表名 --columns` +- 获取指定表字段值:`sqlmap -u 目标网址 -T 表名 -C 字段名1,字段名2,字段名3 --dump` +- 获取指定表字段所有值:`sqlmap -u 目标网址 -T 表名 -C 字段名1,字段名2,字段名3 --dump-all` +- 让 HTTP 请求之间添加延迟,添加参数:`--delay 3`,单位是秒 +- 设置超时时间,默认是 30 秒,添加参数:`--timeout 50`,单位是秒 +- 设置超时后最大重试次数,默认是 3 次,添加参数:`--retries 5` +- 避免错误请求过多而被屏蔽: + +``` +有时服务器检测到某个客户端错误请求过多会对其进行屏蔽,而 sqlmap 的测试往往会产生大量错误请求,为避免被屏蔽,可以时不时的产生几个正常请求以迷惑服务器。有以下四个参数与这一机制有关: + +--safe-url: 隔一会就访问一下的安全 URL +--safe-post: 访问安全 URL 时携带的 POST 数据 +--safe-req: 从文件中载入安全 HTTP 请求 +--safe-freq: 每次测试请求之后都会访问一下的安全 URL + +这里所谓的安全 URL 是指访问会返回 200、没有任何报错的 URL。相应地,Sqlmap 也不会对安全 URL 进行任何注入测试。 +``` + +- 其他常用参数: + - 构造随机 user-agent:`–random-agent` + - 指定 HTTP Referer头:`–referer=设定值` + - 换行分开,加入其他的HTTP头:`–headers=设定值` + - 忽略响应的 Set–Cookie 头信息:`–drop-set-cookie` + +## 分析登录后台入口 + +- nikto + +## 资料 + +- +- +- <> +- <> +- <> +- <> +- <> +- <> +- <> +- <> \ No newline at end of file diff --git a/markdown-file/kali-linux-settings/kali-linux-toc.md b/markdown-file/kali-linux-settings/kali-linux-toc.md new file mode 100644 index 00000000..6c3bd1aa --- /dev/null +++ b/markdown-file/kali-linux-settings/kali-linux-toc.md @@ -0,0 +1,26 @@ + +# Kali Linux + +## 介绍 + +- 官网: +- 基于 Debian +- 设计用于数字鉴识和渗透测试,预装了很多渗透测试程序 +- 支持 x86 和 ARM 架构 +- 官网下载: + - 镜像名:Kali Linux 64 Bit,默认是用 GNOME 桌面,比较华丽,相对较卡(好点电脑推荐,习惯 Ubuntu 的基本都会用) + - 镜像名:Kali Linux Xfce 64 Bit,默认是用 Xfce 桌面,比较简洁,相对不卡(配置较差的推荐,我这里一台笔记本配置较差,用的就是这个) + - 镜像名:Kali Linux Kde 64 Bit,默认是用 Kde 桌面,比较华丽,相对较卡(不推荐) + - 镜像名:Kali Linux Mate 64 Bit,默认是用 Mate 桌面,比较华丽,相对较卡(不推荐) + - 镜像名:Kali Linux Lxde 64 Bit,默认是用 Lxde 桌面,比较简洁,相对不卡(类似 Windows 风格的桌面,不推荐) + +## 学习过程 + +- [Kali Linux 系统安装](kali-linux-install.md) +- [Kali Linux 基础设置](kali-linux-basic-settings.md) +- [Kali Linux 渗透测试思路](kali-linux-penetration-test.md) + + +## 其他资料 + +- \ No newline at end of file diff --git a/maintenance.md b/markdown-file/maintenance.md similarity index 100% rename from maintenance.md rename to markdown-file/maintenance.md diff --git a/markdown-file/monitor.md b/markdown-file/monitor.md new file mode 100644 index 00000000..9a825839 --- /dev/null +++ b/markdown-file/monitor.md @@ -0,0 +1,937 @@ +# 常见日常监控 + +## 系统信息 + +- 查看 CentOS 版本号:`cat /etc/redhat-release` + +--------------------------------------------------------------------- + +## 综合监控 + +- [nmon](Nmon.md) + + + +--------------------------------------------------------------------- + + +## 系统负载 + +#### 命令:w(判断整体瓶颈) + +``` + 12:04:52 up 16 days, 12:54, 1 user, load average: 0.06, 0.13, 0.12 +USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT +root pts/0 116.21.24.85 11:57 4.00s 16:18 0.01s w +``` + +- 第一行: + - `12:04:52` 表示当前系统时间 + - `up 16 days` 表示系统运行时间 + - `1 user` 表示登录用户数 + - `load average` 表示平均负载,0.06 表示一分钟内系统的平均负载值,0.13 表示五分钟内系统的平均负载值,0.12 表示十五分钟内系统的平均负载值。一般这个字不要超过服务器的 CPU 线程数(process)就没有关系。 + - 查看 CPU 总的线程数:`grep 'processor' /proc/cpuinfo | sort -u | wc -l` +- 第二行: + - 开始表示各个登录用户的情况,当前登录者是 root,登录者 IP 116.21.24.85 +- 还有一个简化版本的命令:`uptime` + +``` +10:56:16 up 26 days, 20:05, 1 user, load average: 0.00, 0.01, 0.05 +``` + + +#### 命令:vmstat(判断 RAM 和 I/0 瓶颈) + +- 命令:`vmstat 5 10`,每 5 秒采样一次,共 10 次。 + +``` +procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- + r b swpd free buff cache si so bi bo in cs us sy id wa st + 2 0 0 72648 0 674564 0 0 0 7 0 26 1 1 99 0 0 + 0 0 0 72648 0 674596 0 0 0 0 442 557 1 0 99 0 0 + 0 0 0 72648 0 674596 0 0 0 12 438 574 0 1 99 0 0 + 0 0 0 72648 0 674596 0 0 0 0 430 540 0 0 100 0 0 + 0 0 0 72648 0 674596 0 0 0 0 448 567 0 1 99 0 0 + 0 0 0 72648 0 674596 0 0 0 0 459 574 1 0 99 0 0 + 0 0 0 72648 0 674596 0 0 0 0 425 543 0 1 99 0 0 + 0 0 0 72276 0 674600 0 0 0 0 480 643 2 3 95 0 0 +``` + +- 第二行: + - `r` 表示运行和等待CPU时间片的进程数,该数字如果长期大于服务器CPU的进程数,则说明CPU不够用了。 + - `b` 表示等待资源的进程数,比如等I/O,内存等。该数字如果长时间大于 1,则需要关注一下。 + - `si` 表示由交换区写入到内存的数据量 + - `so` 表示由内存写入到交换区的数据量 + - **如果 si 和 so 的数字比较高,并且不断变化时,说明内存不够了。而且不断变化也表示对系统性能影响很大。** + - `bi` 表示从块设备读取数据的量(读磁盘) + - `bo` 表示从块设备写入数据的量(写磁盘) + - **如果bi和bo两个数字比较高,则说明,磁盘IO压力大。** + - `in` 每秒 CPU 的中断次数,包括时间中断 + - `cs` 每秒上下文切换次数,例如我们调用系统函数,就要进行上下文切换,线程的切换,也要进程上下文切换,这个值要越小越好,太大了,要考虑调低线程或者进程的数目 + - `wa` 表示I/O等待所占用CPU的时间比 + +#### 命令:sar(综合) + +- sar(system activity reporter 系统活动情况报告) +- sar 是目前 linux 上最为全面的系统性能分析工具之一,可以从多方面对系统的活动情况进行报告。包括(文件的读写、系统调用、磁盘I/O、cpu效率、内存使用、进程活动以及IPC有关的活动) +- 如果没安装,运行:`yum install -y sysstat` + +##### sar 之 CPU 使用情况(判断 CPU 瓶颈) + +- 命令:`sar -u 5 10`,每 5 秒采样一次,共 10 次 + +``` +01:57:29 PM CPU %user %nice %system %iowait %steal %idle +01:57:34 PM all 1.81 0.00 0.40 0.00 0.00 97.78 +01:57:39 PM all 0.20 0.00 0.40 0.00 0.00 99.39 +01:57:44 PM all 0.40 0.00 0.60 0.00 0.00 98.99 +01:57:49 PM all 0.20 0.00 0.40 0.00 0.00 99.39 +01:57:54 PM all 0.80 0.00 1.41 0.00 0.00 97.79 +01:57:59 PM all 0.40 0.00 0.60 0.00 0.00 98.99 +01:58:04 PM all 0.20 0.00 0.40 0.00 0.00 99.39 +01:58:09 PM all 0.20 0.00 0.40 0.00 0.00 99.39 +01:58:14 PM all 0.40 0.00 0.61 0.00 0.00 98.99 +01:58:19 PM all 0.20 0.00 0.61 0.00 0.00 99.19 +Average: all 0.48 0.00 0.59 0.00 0.00 98.93 +``` + +- 列说明: + - `CPU:all` 表示统计信息为所有 CPU的平均值。 + - `%user`:显示在用户级别(application)运行使用 CPU 总时间的百分比。 + - `%nice`:显示在用户级别,用于nice操作,所占用 CPU总时间的百分比。 + - `%system`:在核心级别(kernel)运行所使用 CPU总时间的百分比。 + - `%iowait`:显示用于等待I/O操作占用 CPU总时间的百分比。 + - `%steal`:管理程序(hypervisor)为另一个虚拟进程提供服务而等待虚拟 CPU 的百分比。 + - `%idle`:显示 CPU空闲时间占用 CPU总时间的百分比。 +- **总结**: + - 1.若 `%iowait` 的值过高,表示硬盘存在I/O瓶颈 + - 2.若 `%idle` 的值高但系统响应慢时,有可能是 CPU 等待分配内存,此时应加大内存容量,可以使用内存监控命令分析内存。 + - 3.若 `%idle` 的值持续低于1,则系统的 CPU 处理能力相对较低,表明系统中最需要解决的资源是 CPU。 + +##### sar 之 RAM 使用情况(判断内存瓶颈) + +- 命令:`sar -B 5 10`,每 5 秒采样一次,共 10 次 + +``` +02:32:15 PM pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/s pgscand/s pgsteal/s %vmeff +02:32:20 PM 0.00 0.81 258.47 0.00 27.22 0.00 0.00 0.00 0.00 +02:32:25 PM 0.00 0.00 611.54 0.00 300.20 0.00 0.00 0.00 0.00 +02:32:30 PM 0.00 26.61 10.08 0.00 11.90 0.00 0.00 0.00 0.00 +02:32:35 PM 0.00 1.62 3.64 0.00 3.84 0.00 0.00 0.00 0.00 +02:32:40 PM 0.00 0.00 3.42 0.00 4.43 0.00 0.00 0.00 0.00 +02:32:45 PM 0.00 0.00 3.43 0.00 3.83 0.00 0.00 0.00 0.00 +02:32:50 PM 0.00 1.62 3.84 0.00 5.86 0.00 0.00 0.00 0.00 +02:32:55 PM 0.00 0.00 3.41 0.00 3.82 0.00 0.00 0.00 0.00 +02:33:00 PM 0.00 2.42 763.84 0.00 208.69 0.00 0.00 0.00 0.00 +02:33:05 PM 0.00 13.74 2409.70 0.00 929.70 0.00 0.00 0.00 0.00 +Average: 0.00 4.68 406.50 0.00 149.69 0.00 0.00 0.00 0.00 +``` + +- `pgpgin/s`:表示每秒从磁盘或SWAP置换到内存的字节数(KB) +- `pgpgout/s`:表示每秒从内存置换到磁盘或SWAP的字节数(KB) +- `fault/s`:每秒钟系统产生的缺页数,即主缺页与次缺页之和(major + minor) +- `majflt/s`:每秒钟产生的主缺页数 +- `pgfree/s`:每秒被放入空闲队列中的页个数 +- `pgscank/s`:每秒被kswapd扫描的页个数 +- `pgscand/s`:每秒直接被扫描的页个数 +- `pgsteal/s`:每秒钟从cache中被清除来满足内存需要的页个数 +- `%vmeff`:每秒清除的页(pgsteal)占总扫描页(pgscank+pgscand)的百分比 + +##### sar 之 I/O 使用情况(判断 I/O 瓶颈) + +- 命令:`sar -b 5 10`,每 5 秒采样一次,共 10 次 + +``` +02:34:13 PM tps rtps wtps bread/s bwrtn/s +02:34:18 PM 3.03 0.00 3.03 0.00 59.80 +02:34:23 PM 0.00 0.00 0.00 0.00 0.00 +02:34:28 PM 0.00 0.00 0.00 0.00 0.00 +02:34:33 PM 0.00 0.00 0.00 0.00 0.00 +02:34:38 PM 1.61 0.00 1.61 0.00 24.80 +02:34:43 PM 0.00 0.00 0.00 0.00 0.00 +02:34:48 PM 0.40 0.00 0.40 0.00 4.86 +02:34:53 PM 0.00 0.00 0.00 0.00 0.00 +02:34:58 PM 0.00 0.00 0.00 0.00 0.00 +02:35:03 PM 0.00 0.00 0.00 0.00 0.00 +Average: 0.50 0.00 0.50 0.00 8.94 +``` + +- `tps`:每秒钟物理设备的 I/O 传输总量 +- `rtps`:每秒钟从物理设备读入的数据总量 +- `wtps`:每秒钟向物理设备写入的数据总量 +- `bread/s`:每秒钟从物理设备读入的数据量,单位为块/s +- `bwrtn/s`:每秒钟向物理设备写入的数据量,单位为块/s + +##### sar 之 DEV(网卡)流量查看(判断网络瓶颈) + +- 命令:`sar -n DEV`,查看网卡历史流量(因为是按时间显示每棵的流量,所以有很多) +- 如果要动态显示当前的网卡流量:`sar -n DEV 1` +- 采样收集网卡流量:`sar -n DEV 5 10`,每 5 秒采样一次,共 10 次 +- 如果要查看其他日期下的记录,可以到这个目录下:`cd /var/log/sa` 查看下记录的文件,然后选择一个文件,比如:`sar -n DEV -f /var/log/sa/sa01`) + +``` +01:46:24 PM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s +01:46:25 PM lo 3.00 3.00 0.18 0.18 0.00 0.00 0.00 +01:46:25 PM eth0 4.00 4.00 0.55 0.56 0.00 0.00 0.00 +``` + +- `01:46:25 PM` 表示时间 +- `IFACE` 表示网卡名称 +- `rxpck/s` 每秒钟接收到的 **包数目**,一般如果这个数字大于 4000 一般是被攻击了。 +- `txpck/s` 每秒钟发送出去的 **包数目** +- `rxkB/s` 每秒钟接收到的数据量(单位kb),一般如果这个数字大于 5000 一般是被攻击了。 +- `txkB/s` 每秒钟发送出去的数据量(单位kb) +- `rxcmp/s`:每秒钟接收到的压缩包数目 +- `txcmp/s`:每秒钟发送出去的压缩包数目 +- `txmcst/s`:每秒钟接收到的多播包的包数目 + +- 查看 TCP 相关的一些数据(每隔 1 秒采样一次,一共 5 次):`sar -n TCP,ETCP 1 5` + +``` +Linux 3.10.0-693.2.2.el7.x86_64 (youmeek) 07/17/2018 _x86_64_ (2 CPU) + +12:05:47 PM active/s passive/s iseg/s oseg/s +12:05:48 PM 0.00 0.00 1.00 0.00 + +12:05:47 PM atmptf/s estres/s retrans/s isegerr/s orsts/s +12:05:48 PM 0.00 0.00 0.00 0.00 0.00 + +12:05:48 PM active/s passive/s iseg/s oseg/s +12:05:49 PM 0.00 0.00 1.00 1.00 + +12:05:48 PM atmptf/s estres/s retrans/s isegerr/s orsts/s +12:05:49 PM 0.00 0.00 0.00 0.00 0.00 + +12:05:49 PM active/s passive/s iseg/s oseg/s +12:05:50 PM 0.00 0.00 1.00 1.00 + +12:05:49 PM atmptf/s estres/s retrans/s isegerr/s orsts/s +12:05:50 PM 0.00 0.00 0.00 0.00 0.00 + +12:05:50 PM active/s passive/s iseg/s oseg/s +12:05:51 PM 0.00 0.00 3.00 3.00 + +12:05:50 PM atmptf/s estres/s retrans/s isegerr/s orsts/s +12:05:51 PM 0.00 0.00 0.00 0.00 0.00 + +12:05:51 PM active/s passive/s iseg/s oseg/s +12:05:52 PM 0.00 0.00 1.00 1.00 + +12:05:51 PM atmptf/s estres/s retrans/s isegerr/s orsts/s +12:05:52 PM 0.00 0.00 0.00 0.00 0.00 + +Average: active/s passive/s iseg/s oseg/s +Average: 0.00 0.00 1.40 1.20 + +Average: atmptf/s estres/s retrans/s isegerr/s orsts/s +Average: 0.00 0.00 0.00 0.00 0.00 +``` + + +``` +- active/s:每秒钟本地主动开启的 tcp 连接,也就是本地程序使用 connect() 系统调用 +- passive/s:每秒钟从源端发起的 tcp 连接,也就是本地程序使用 accept() 所接受的连接 +- retrans/s: 每秒钟的 tcp 重传次数 + +atctive 和 passive 的数目通常可以用来衡量服务器的负载:接受连接的个数(passive),下游连接的个数(active)。可以简单认为 active 为出主机的连接,passive 为入主机的连接;但这个不是很严格的说法,比如 loalhost 和 localhost 之间的连接。 + +来自:https://zhuanlan.zhihu.com/p/39893236 +``` + +--------------------------------------------------------------------- + +## CPU 监控 + +#### CPU 的基本信息查看 + +- Demo CPU 型号:[Intel® Xeon® Processor E5-2620 v2(15M Cache, 2.10 GHz)](http://ark.intel.com/products/75789/Intel-Xeon-Processor-E5-2620-v2-15M-Cache-2_10-GHz) +- 该 CPU 显示的数据中有一项这个要注意:`Intel® Hyper-Threading Technology` 是 `Yes`。表示该 CPU 支持超线程 +- `cat /proc/cpuinfo`,查看 CPU 总体信息 +- `grep 'physical id' /proc/cpuinfo | sort -u | wc -l`,查看物理 CPU 个数 + - 结果:2 + - 物理 CPU:物理 CPU 也就是机器外面就能看到的一个个 CPU,每个物理 CPU 还带有单独的风扇 +- `grep 'core id' /proc/cpuinfo | sort -u | wc -l`,查看每个物理 CPU 的核心数量 + - 结果:6,因为每个物理 CPU 是 6,所有 2 个物理 CPU 的总核心数量应该是:12 + - 核心数:一个核心就是一个物理线程,英特尔有个超线程技术可以把一个物理线程模拟出两个线程来用,充分发挥 CPU 性能,意思是一个核心可以有多个线程。 +- `grep 'processor' /proc/cpuinfo | sort -u | wc -l`,查看 CPU 总的线程数,一般也叫做:逻辑 CPU 数量 + - 结果:24,正常情况下:CPU 的总核心数量 == CPU 线程数,但是如果该 CPU 支持超线程,那结果是:CPU 的总核心数量 X 2 == CPU 线程数 + - 线程数:线程数是一种逻辑的概念,简单地说,就是模拟出的 CPU 核心数。比如,可以通过一个 CPU 核心数模拟出 2 线程的 CPU,也就是说,这个单核心的 CPU 被模拟成了一个类似双核心 CPU 的功能。 + + +#### CPU 监控 + +- Linux 的 CPU 简单监控一般简单 +- 常用命令就是 `top` + - 命令:`top -bn1`,可以完全显示所有进程出来,但是不能实时展示数据,只能暂时命令当时的数据。 +- `top` 可以动态显示进程所占的系统资源,每隔 3 秒变一次,占用系统资源最高的进程放最前面。 +- 在 `top` 命令状态下还可以按数字键 1 显示各个 CPU 线程使用状态 +- 在 `top` 命令状态下按 shfit + m 可以按照 **内存使用** 大小排序 +- 在 `top` 命令状态下按 shfit + p 可以按照 **CPU 使用** 大小排序 +- 展示数据上,%CPU 表示进程占用的 CPU 百分比,%MEM 表示进程占用的内存百分比 +- mac 下不一样:要先输入 o,然后输入 cpu 则按 cpu 使用量排序,输入 rsize 则按内存使用量排序。 + +#### CPU 其他工具 + +- htop 综合工具:`yum install -y htop` + - 这几篇文章讲得很好,我没必要再贴过来了,大家自己看: + - [htop 命令完胜 top 命令](http://blog.51cto.com/215687833/1788493) + - [htop 命令详解](https://blog.csdn.net/freeking101/article/details/79173903) +- mpstat 实时监控 CPU 状态:`yum install -y sysstat` + - 可以具体到某个核心,比如我有 2 核的 CPU,因为 CPU 核心下标是从 0 开始,所以我要查看 0 的状况(间隔 3 秒获取一次指标,一共获取 5 次):`mpstat -P 0 3 5` + - 打印总 CPU 和各个核心指标:`mpstat -P ALL 1` + - 获取所有核心的平均值:`mpstat 3 5` + +``` +Linux 3.10.0-693.2.2.el7.x86_64 (iZwz998aag1ggy168n3wg2Z) 06/23/2018 _x86_64_ (2 CPU) + +11:44:52 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle +11:44:53 AM 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 +11:44:54 AM 0 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 99.00 +11:44:55 AM 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 +11:44:56 AM 0 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 99.00 +11:44:57 AM 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 +Average: 0 0.20 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 99.60 +``` + +- %usr 用户进程消耗 CPU 情况 +- %sys 系统进程消耗 CPU 情况 +- %iowait 表示 CPU 等待 IO 时间占整个 CPU 周期的百分比 +- %idle 显示 CPU 空闲时间占用 CPU 总时间的百分比 + +#### 类似 top 的 pidstat + +- 安装:`yum install -y sysstat` +- 每隔 2 秒采样一次,一共 5 次:`pidstat 2 5` + +``` +Linux 3.10.0-693.el7.x86_64 (youmeek) 07/17/2018 _x86_64_ (8 CPU) + +11:52:58 AM UID PID %usr %system %guest %CPU CPU Command +11:53:00 AM 0 16813 0.50 0.99 0.00 1.49 1 pidstat +11:53:00 AM 0 24757 50.99 12.87 0.00 63.86 0 java +11:53:00 AM 0 24799 60.40 3.47 0.00 63.86 5 java +11:53:00 AM 0 24841 99.50 7.43 0.00 100.00 0 java + +11:53:00 AM UID PID %usr %system %guest %CPU CPU Command +11:53:02 AM 0 24757 56.50 0.50 0.00 57.00 0 java +11:53:02 AM 0 24799 100.00 6.50 0.00 100.00 5 java +11:53:02 AM 0 24841 58.00 2.50 0.00 60.50 0 java + +11:53:02 AM UID PID %usr %system %guest %CPU CPU Command +11:53:04 AM 0 16813 0.00 1.00 0.00 1.00 2 pidstat +11:53:04 AM 0 24757 62.00 5.50 0.00 67.50 0 java +11:53:04 AM 0 24799 54.00 14.00 0.00 68.00 5 java +11:53:04 AM 0 24841 39.50 9.00 0.00 48.50 0 java + +11:53:04 AM UID PID %usr %system %guest %CPU CPU Command +11:53:06 AM 0 16813 0.50 0.50 0.00 1.00 2 pidstat +11:53:06 AM 0 24757 80.00 13.50 0.00 93.50 0 java +11:53:06 AM 0 24799 56.50 0.50 0.00 57.00 5 java +11:53:06 AM 0 24841 1.00 0.50 0.00 1.50 0 java + +11:53:06 AM UID PID %usr %system %guest %CPU CPU Command +11:53:08 AM 0 16813 0.00 0.50 0.00 0.50 2 pidstat +11:53:08 AM 0 24757 58.50 1.00 0.00 59.50 0 java +11:53:08 AM 0 24799 60.00 1.50 0.00 61.50 5 java +11:53:08 AM 0 24841 1.00 0.50 0.00 1.50 0 java + +Average: UID PID %usr %system %guest %CPU CPU Command +Average: 0 16813 0.20 0.60 0.00 0.80 - pidstat +Average: 0 24757 61.58 6.69 0.00 68.26 - java +Average: 0 24799 66.47 5.19 0.00 71.66 - java +Average: 0 24841 39.92 3.99 0.00 43.91 - java +``` + +--------------------------------------------------------------------- + + +## 内存监控 + +- Linux 的内存本质是虚拟内存,这样说是因为它的内存是:物理内存 + 交换分区。有一个内存模块来管理应用的内存使用。 +- 如果所以你内存大,可以考虑把 swap 分区改得小点或者直接关掉。 +- 但是,如果是用的云主机,一般是没交换分区的,`free -g` 中的 Swap 都是 0。 +- 查看内存使用命令: + - 以 M 为容量单位展示数据:`free -m` + - 以 G 为容量单位展示数据:`free -g` + - CentOS 6 和 CentOS 7 展示出来的数据有差别,CentOS 7 比较容易看,比如下面的数据格式是 CentOS 7 的 `free -g`: + +``` + total used free shared buff/cache available +Mem: 11 0 10 0 0 10 +Swap: 5 0 5 + +``` + +- 在以上结果中,其中可以用的内存是看 `available` 列。 +- 对于 CentOS 6 的系统可以使用下面命令: + +``` +[root@bogon ~]# free -mlt + total used free shared buffers cached +Mem: 16080 15919 160 0 278 11934 +Low: 16080 15919 160 +High: 0 0 0 +-/+ buffers/cache: 3706 12373 +Swap: 0 0 0 +Total: 16080 15919 160 +``` + +- 以上的结果重点关注是:`-/+ buffers/cache`,这一行代表实际使用情况。 + + +##### pidstat 采样内存使用情况 + +- 安装:`yum install -y sysstat` +- 每隔 2 秒采样一次,一共 3 次:`pidstat -r 2 3` + +``` +Linux 3.10.0-693.el7.x86_64 (youmeek) 07/17/2018 _x86_64_ (8 CPU) + +11:56:34 AM UID PID minflt/s majflt/s VSZ RSS %MEM Command +11:56:36 AM 0 23960 168.81 0.00 108312 1124 0.01 pidstat +11:56:36 AM 0 24757 8.42 0.00 9360696 3862788 23.75 java +11:56:36 AM 0 24799 8.91 0.00 10424088 4988468 30.67 java +11:56:36 AM 0 24841 11.39 0.00 10423576 4968428 30.54 java + +11:56:36 AM UID PID minflt/s majflt/s VSZ RSS %MEM Command +11:56:38 AM 0 23960 169.50 0.00 108312 1200 0.01 pidstat +11:56:38 AM 0 24757 6.00 0.00 9360696 3862788 23.75 java +11:56:38 AM 0 24799 5.50 0.00 10424088 4988468 30.67 java +11:56:38 AM 0 24841 7.00 0.00 10423576 4968428 30.54 java + +11:56:38 AM UID PID minflt/s majflt/s VSZ RSS %MEM Command +11:56:40 AM 0 23960 160.00 0.00 108312 1200 0.01 pidstat +11:56:40 AM 0 24757 6.50 0.00 9360696 3862788 23.75 java +11:56:40 AM 0 24799 6.00 0.00 10424088 4988468 30.67 java +11:56:40 AM 0 24841 8.00 0.00 10423576 4968428 30.54 java + +Average: UID PID minflt/s majflt/s VSZ RSS %MEM Command +Average: 0 23960 166.11 0.00 108312 1175 0.01 pidstat +Average: 0 24757 6.98 0.00 9360696 3862788 23.75 java +Average: 0 24799 6.81 0.00 10424088 4988468 30.67 java +Average: 0 24841 8.80 0.00 10423576 4968428 30.54 java +``` + + +--------------------------------------------------------------------- + +## 硬盘监控 + +#### 硬盘容量相关查看 + +- `df -h`:自动以合适的磁盘容量单位查看磁盘大小和使用空间 +- `df -m`:以磁盘容量单位 M 为数值结果查看磁盘使用情况 +- `du -sh /opt/tomcat6`:查看tomcat6这个文件夹大小 (h的意思human-readable用人类可读性较好方式显示,系统会自动调节单位,显示合适大小的单位) +- `du /opt --max-depth=1 -h`:查看指定录入下包括子目录的各个文件大小情况 + + +#### 命令:iostat(判断 I/0 瓶颈) + +- 命令:`iostat -x -k 3 3`,每 3 秒采样一次,共 3 次。 + +``` +avg-cpu: %user %nice %system %iowait %steal %idle + 0.55 0.00 0.52 0.00 0.00 98.93 + +Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util +vda 0.00 0.04 0.02 0.62 0.44 6.49 21.65 0.00 1.42 1.17 1.42 0.25 0.02 + +avg-cpu: %user %nice %system %iowait %steal %idle + 0.34 0.00 0.00 0.00 0.00 99.66 + +Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util +vda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +avg-cpu: %user %nice %system %iowait %steal %idle + 2.02 0.00 0.34 0.00 0.00 97.64 + +Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util +vda 0.00 0.00 0.00 1.68 0.00 16.16 19.20 0.00 0.20 0.00 0.20 0.20 0.03 +``` + +- 列说明: + - `rrqm/s`: 每秒对该设备的读请求被合并次数,文件系统会对读取同块(block)的请求进行合并 + - `wrqm/s`: 每秒对该设备的写请求被合并次数 + - `r/s`: 每秒完成的读次数 + - `w/s`: 每秒完成的写次数 + - `rkB/s`: 每秒读数据量(kB为单位) + - `wkB/s`: 每秒写数据量(kB为单位) + - `avgrq-sz`:平均每次IO操作的数据量(扇区数为单位) + - `avgqu-sz`: 平均等待处理的IO请求队列长度(队列长度大于 1 表示设备处于饱和状态。) + - `await`: 系统发往 IO 设备的请求的平均响应时间(毫秒为单位)。这包括请求排队的时间,以及请求处理的时间。超过经验值的平均响应时间表明设备处于饱和状态,或者设备有问题。 + - `svctm`: 平均每次IO请求的处理时间(毫秒为单位) + - `%util`: 采用周期内用于IO操作的时间比率,即IO队列非空的时间比率(就是繁忙程度,值越高表示越繁忙) +- **总结** + - `iowait%` 表示CPU等待IO时间占整个CPU周期的百分比,如果iowait值超过50%,或者明显大于%system、%user以及%idle,表示IO可能存在问题。 + - `%util` (重点参数)表示磁盘忙碌情况,一般该值超过80%表示该磁盘可能处于繁忙状态 + + +#### 硬盘 IO 监控 + +- 安装 iotop:`yum install -y iotop` +- 查看所有进程 I/O 情况命令:`iotop` +- 只查看当前正在处理 I/O 的进程:`iotop -o` +- 只查看当前正在处理 I/O 的线程,每隔 5 秒刷新一次:`iotop -o -d 5` +- 只查看当前正在处理 I/O 的进程(-P 参数决定),每隔 5 秒刷新一次:`iotop -o -P -d 5` +- 只查看当前正在处理 I/O 的进程(-P 参数决定),每隔 5 秒刷新一次,使用 KB/s 单位(默认是 B/s):`iotop -o -P -k -d 5` +- 使用 dd 命令测量服务器延迟:`dd if=/dev/zero of=/opt/ioTest2.txt bs=512 count=1000 oflag=dsync` +- 使用 dd 命令来测量服务器的吞吐率(写速度):`dd if=/dev/zero of=/opt/ioTest1.txt bs=1G count=1 oflag=dsync` + - 该命令创建了一个 10M 大小的文件 ioTest1.txt,其中参数解释: + - if 代表输入文件。如果不指定 if,默认就会从 stdin 中读取输入。 + - of 代表输出文件。如果不指定 of,默认就会将 stdout 作为默认输出。 + - bs 代表字节为单位的块大小。 + - count 代表被复制的块数。 + - /dev/zero 是一个字符设备,会不断返回0值字节(\0)。 + - oflag=dsync:使用同步I/O。不要省略这个选项。这个选项能够帮助你去除 caching 的影响,以便呈现给你精准的结果。 + - conv=fdatasyn: 这个选项和 oflag=dsync 含义一样。 + +- 该命令执行完成后展示的数据: + +``` +[root@youmeek ~]# dd if=/dev/zero of=/opt/ioTest1.txt bs=1G count=1 oflag=dsync +记录了1+0 的读入 +记录了1+0 的写出 +1073741824字节(1.1 GB)已复制,5.43328 秒,198 MB/秒 +``` + +- 利用 hdparm 测试硬盘速度:`yum install -y hdparm` +- 查看硬盘分区情况:`df -h`,然后根据分区测试: +- 测试硬盘分区的读取速度:`hdparm -T /dev/sda` +- 测试硬盘分区缓存的读取速度:`hdparm -t /dev/sda` +- 也可以以上两个参数一起测试:`hdparm -Tt /dev/sda`,结果数据如下: + +``` +/dev/sda: +Timing cached reads: 3462 MB in 2.00 seconds = 1731.24 MB/sec +Timing buffered disk reads: 806 MB in 3.00 seconds = 268.52 MB/sec +``` + + +##### pidstat 采样硬盘使用情况 + +- 安装:`yum install -y sysstat` +- 每隔 2 秒采样一次,一共 3 次:`pidstat -d 2 3` + +``` +Linux 3.10.0-693.el7.x86_64 (youmeek) 07/17/2018 _x86_64_ (8 CPU) + +11:57:29 AM UID PID kB_rd/s kB_wr/s kB_ccwr/s Command + +11:57:31 AM UID PID kB_rd/s kB_wr/s kB_ccwr/s Command +11:57:33 AM 0 24757 0.00 2.00 0.00 java +11:57:33 AM 0 24799 0.00 14.00 0.00 java + +11:57:33 AM UID PID kB_rd/s kB_wr/s kB_ccwr/s Command +11:57:35 AM 0 24841 0.00 8.00 0.00 java + +Average: UID PID kB_rd/s kB_wr/s kB_ccwr/s Command +Average: 0 24757 0.00 0.66 0.00 java +Average: 0 24799 0.00 4.65 0.00 java +Average: 0 24841 0.00 2.66 0.00 java +``` + +- 输出指标含义: + +``` +kB_rd/s: 每秒进程从磁盘读取的数据量(以 kB 为单位) +kB_wr/s: 每秒进程向磁盘写的数据量(以 kB 为单位) +kB_ccwr/s:任务取消的写入磁盘的 KB。当任务截断脏的 pagecache 的时候会发生。 +``` + + +--------------------------------------------------------------------- + + +## 网络监控 + +#### 网络监控常用 + +- 安装 iftop(需要有 EPEL 源):`yum install -y iftop` + - 如果没有 EPEL 源:`yum install -y epel-release` +- 常用命令: + - `iftop`:默认是监控第一块网卡的流量 + - `iftop -i eth0`:监控 eth0 + - `iftop -n`:直接显示IP, 不进行DNS反解析 + - `iftop -N`:直接显示连接埠编号, 不显示服务名称 + - `iftop -F 192.168.1.0/24 or 192.168.1.0/255.255.255.0`:显示某个网段进出封包流量 + - `iftop -nP`:显示端口与 IP 信息 + +``` nginx +中间部分:外部连接列表,即记录了哪些ip正在和本机的网络连接 + +右边部分:实时参数分别是该访问 ip 连接到本机 2 秒,10 秒和 40 秒的平均流量 + +=> 代表发送数据,<= 代表接收数据 + +底部会显示一些全局的统计数据,peek 是指峰值情况,cumm 是从 iftop 运行至今的累计情况,而 rates 表示最近 2 秒、10 秒、40 秒内总共接收或者发送的平均网络流量。 + +TX:(发送流量) cumm: 143MB peak: 10.5Mb rates: 1.03Mb 1.54Mb 2.10Mb +RX:(接收流量) 12.7GB 228Mb 189Mb 191Mb 183Mb +TOTAL:(总的流量) 12.9GB 229Mb 190Mb 193Mb 185MbW + +``` + +### 端口使用情况(也可以用来查看端口占用) + +#### lsof + +- 安装 lsof:`yum install -y lsof` +- 查看 3316 端口是否有被使用(macOS 也适用):`lsof -i:3316`,**有被使用会输出类似如下信息,如果没被使用会没有任何信息返回** + +``` +COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME +java 12011 root 77u IPv6 4506842 0t0 TCP JDu4e00u53f7:58560->116.196.110.69:aicc-cmi (ESTABLISHED) +java 12011 root 78u IPv6 4506843 0t0 TCP JDu4e00u53f7:58576->116.196.110.69:aicc-cmi (ESTABLISHED) +java 12011 root 79u IPv6 4506844 0t0 TCP JDu4e00u53f7:58578->116.196.110.69:aicc-cmi (ESTABLISHED) +java 12011 root 80u IPv6 4506845 0t0 TCP JDu4e00u53f7:58574->116.196.110.69:aicc-cmi (ESTABLISHED) +java 12011 root 82u IPv6 4506846 0t0 TCP JDu4e00u53f7:58562->116.196.110.69:aicc-cmi (ESTABLISHED) +java 12011 root 83u IPv6 4506847 0t0 TCP JDu4e00u53f7:58564->116.196.110.69:aicc-cmi (ESTABLISHED) +java 12011 root 84u IPv6 4506848 0t0 TCP JDu4e00u53f7:58566->116.196.110.69:aicc-cmi (ESTABLISHED) +java 12011 root 85u IPv6 4506849 0t0 TCP JDu4e00u53f7:58568->116.196.110.69:aicc-cmi (ESTABLISHED) +java 12011 root 86u IPv6 4506850 0t0 TCP JDu4e00u53f7:58570->116.196.110.69:aicc-cmi (ESTABLISHED) +java 12011 root 87u IPv6 4506851 0t0 TCP JDu4e00u53f7:58572->116.196.110.69:aicc-cmi (ESTABLISHED) +docker-pr 13551 root 4u IPv6 2116824 0t0 TCP *:aicc-cmi (LISTEN) +``` + +#### netstat + +- 更多用法可以看:[netstat 的10个基本用法](https://linux.cn/article-2434-1.html) +- 查看所有在用的端口(macOS 也适用):`netstat -ntlp` + +``` +Active Internet connections (only servers) +Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name +tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1/systemd +tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 746/sshd +tcp 0 0 127.0.0.1:32000 0.0.0.0:* LISTEN 12011/java +tcp6 0 0 :::9066 :::* LISTEN 12011/java +tcp6 0 0 :::6379 :::* LISTEN 28668/docker-proxy +tcp6 0 0 :::111 :::* LISTEN 1/systemd +tcp6 0 0 :::3316 :::* LISTEN 13551/docker-proxy +tcp6 0 0 :::22 :::* LISTEN 746/sshd +tcp6 0 0 :::35224 :::* LISTEN 12011/java +tcp6 0 0 :::3326 :::* LISTEN 14203/docker-proxy +tcp6 0 0 :::1984 :::* LISTEN 12011/java +tcp6 0 0 :::8066 :::* LISTEN 12011/java +tcp6 0 0 :::43107 :::* LISTEN 12011/java +``` + +- 查看当前连接80端口的机子有多少,并且是属于什么状态:`netstat -an|grep 80|sort -r` +- 查看已经连接的IP有多少连接数:`netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n` +- 查看已经连接的IP有多少连接数,只显示前 5 个:`netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n | head -5` +- 查看每个 ip 跟服务器建立的连接数:`netstat -nat|awk '{print$5}'|awk -F : '{print$1}'|sort|uniq -c|sort -rn` + +``` +262 127.0.0.1 +118 +103 172.22.100.141 + 12 172.22.100.29 + 7 172.22.100.183 + 6 116.21.17.144 + 6 0.0.0.0 + 5 192.168.1.109 + 4 172.22.100.32 + 4 172.22.100.121 + 4 172.22.100.108 + 4 172.18.1.39 + 3 172.22.100.2 + 3 172.22.100.190 +``` + + +- 统计当前连接的一些状态情况:`netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'` 或者 `netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn` + +``` +TIME_WAIT 96(是表示系统在等待客户端响应,以便再次连接时候能快速响应,如果积压很多,要开始注意了,准备阻塞了。这篇文章可以看下:http://blog.51cto.com/jschu/1728001) +CLOSE_WAIT 11(如果积压很多,要开始注意了,准备阻塞了。可以看这篇文章:http://blog.51cto.com/net881004/2164020) +FIN_WAIT2 17 +ESTABLISHED 102(表示正常数据传输状态) +``` + +- TIME_WAIT 和 CLOSE_WAIT 说明: + +``` +Linux 系统下,TCP连接断开后,会以TIME_WAIT状态保留一定的时间,然后才会释放端口。当并发请求过多的时候,就会产生大量的TIME_WAIT状态 的连接,无法及时断开的话,会占用大量的端口资源和服务器资源。这个时候我们可以优化TCP的内核参数,来及时将TIME_WAIT状态的端口清理掉。 + +来源:http://zhangbin.junxilinux.com/?p=219 + +================================= + +出现大量close_wait的现象,主要原因是某种情况下对方关闭了socket链接,但是另一端由于正在读写,没有关闭连接。代码需要判断socket,一旦读到0,断开连接,read返回负,检查一下errno,如果不是AGAIN,就断开连接。 +Linux分配给一个用户的文件句柄是有限的,而TIME_WAIT和CLOSE_WAIT两种状态如果一直被保持,那么意味着对应数目的通道就一直被占着,一旦达到句柄数上限,新的请求就无法被处理了,接着就是大量Too Many Open Files异常,导致tomcat崩溃。关于TIME_WAIT过多的解决方案参见TIME_WAIT数量太多。 + +常见错误原因: +1.代码层面上未对连接进行关闭,比如关闭代码未写在 finally 块关闭,如果程序中发生异常就会跳过关闭代码,自然未发出指令关闭,连接一直由程序托管,内核也无权处理,自然不会发出 FIN 请求,导致连接一直在 CLOSE_WAIT 。 +2.程序响应过慢,比如双方进行通讯,当客户端请求服务端迟迟得不到响应,就断开连接,重新发起请求,导致服务端一直忙于业务处理,没空去关闭连接。这种情况也会导致这个问题。一般如果有多个节点,nginx 进行负载,其中某个节点很高,其他节点不高,那可能就是负载算法不正常,都落在一台机子上了,以至于它忙不过来。 + +来源:https://juejin.im/post/5b59e61ae51d4519634fe257 +``` + +- 查看网络接口接受、发送的数据包情况(每隔 3 秒统计一次):`netstat -i 3` + + +``` +Kernel Interface table +Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg +eth0 1500 10903298 0 0 0 10847741 0 0 0 BMRU +lo 65536 453650 0 0 0 453650 0 0 0 LRU +eth0 1500 10903335 0 0 0 10847777 0 0 0 BMRU +lo 65536 453650 0 0 0 453650 0 0 0 LRU +eth0 1500 10903363 0 0 0 10847798 0 0 0 BMRU +lo 65536 453650 0 0 0 453650 0 0 0 LRU +eth0 1500 10903393 0 0 0 10847836 0 0 0 BMRU +lo 65536 453650 0 0 0 453650 0 0 0 LRU +eth0 1500 10903437 0 0 0 10847867 0 0 0 BMRU +lo 65536 453650 0 0 0 453650 0 0 0 LRU +``` + +- 接收(该值是历史累加数据,不是瞬间数据,要计算时间内的差值需要自己减): + - RX-OK 已接收字节数 + - RX-ERR 已接收错误字节数(数据值大说明网络存在问题) + - RX-DRP 已丢失字节数(数据值大说明网络存在问题) + - RX-OVR 由于误差而遗失字节数(数据值大说明网络存在问题) +- 发送(该值是历史累加数据,不是瞬间数据,要计算时间内的差值需要自己减): + - TX-OK 已发送字节数 + - TX-ERR 已发送错误字节数(数据值大说明网络存在问题) + - TX-DRP 已丢失字节数(数据值大说明网络存在问题) + - TX-OVR 由于误差而遗失字节数(数据值大说明网络存在问题) + + +#### 网络排查 + +- ping 命令查看丢包、域名解析地址 + - `ping 116.196.110.69` + - `ping www.GitNavi.com` +- telnet 测试端口的连通性(验证服务的可用性) + - `yum install -y telnet` + - `telnet 116.196.110.68 3306` + - `telnet www.youmeek.com 80` +- tracert(跟踪路由)查看网络请求节点访问情况,用于确定 IP 数据报访问目标所采取的路径。 + - `yum install -y traceroute` + - `traceroute gitnavi.com` +- nslookup 命令查看 DNS 是否可用 + - `yum install -y bind-utils` + - 输入:`nslookup`,然后终端进入交互模式,然后输入:`www.baidu.com`,此时会展示类似这样的信息: + +``` +Server: 103.224.222.221(这个是你本机的信息) +Address: 103.224.222.221#53(这个是你本机的信息) + +(下面是百度的信息) +Non-authoritative answer: +www.baidu.COM canonical name = www.a.shifen.COM. +Name: www.a.shifen.COM +Address: 220.181.112.244 +Name: www.a.shifen.COM +Address: 220.181.111.188 +``` + +- 此时我们假设换个 DNS,我们在刚刚的交互阶段继续输入:`server 8.8.8.8`,表示我们此时用 8.8.8.8 的 DNS,然后我们在交互中再输入:`www.baidu.com`,此时会出现这个信息: + +``` +Server: 8.8.8.8 +Address: 8.8.8.8#53 + +Non-authoritative answer: +www.baidu.com canonical name = www.a.shifen.com. +Name: www.a.shifen.com +Address: 180.97.33.108 +Name: www.a.shifen.com +Address: 180.97.33.107 +``` + +- 以上表明,不同的 DNS 情况下,我们获取到的域名所属 IP 是不同的。 + +--------------------------------------------------------------------- + +## 查看 Linux 内核版本 + +- 对于一些复杂的层面问题,一般都要先确认内核版本,好帮助分析:`uname -r` + +``` +3.10.0-693.2.2.el7.x86_64 +``` + + +## dmesg 打印内核信息 + +- 开机信息存在:`tail -500f /var/log/dmesg` +- 查看尾部信息:`dmesg -T | tail` + - 参数 `-T` 表示显示时间 +- 只显示 error 和 warning 信息:`dmesg --level=err,warn -T` +- 有些 OOM 的错误会在这里显示,比如: + +``` +[1880957.563400] Out of memory: Kill process 18694 (perl) score 246 or sacrifice child +[1880957.563408] Killed process 18694 (perl) total-vm:1972392kB, anon-rss:1953348kB, file-rss:0kB +``` + +## 查看系统日志 + +- 查看系统日志:`tail -400f /var/log/messages` +- 可能会看到类似以下异常: + +``` +Out of memory: Kill process 19452 (java) score 264 or sacrifice child +``` + + +--------------------------------------------------------------------- + +## 服务器故障排查顺序 + +#### 请求时好时坏 + +- 系统层面 + - 查看负载、CPU、内存、上线时间、高资源进程 PID:`htop` + - 查看网络丢失情况:`netstat -i 3`,关注:RX-DRP、TX-DRP,如果两个任何一个有值,或者都有值,肯定是网络出了问题(该值是历史累加数据,不是瞬间数据)。 +- 应用层面 + - 临时修改 nginx log 输出格式,输出完整信息,包括请求头 + +``` +$request_body 请求体(含POST数据) +$http_XXX 指定某个请求头(XXX为字段名,全小写) +$cookie_XXX 指定某个cookie值(XXX为字段名,全小写) + + +类似用法: +log_format special_main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$request_body" "$http_referer" ' + '"$http_user_agent" $http_x_forwarded_for "appid=$http_appid,appver=$http_appver,vuser=$http_vuser" ' + '"phpsessid=$cookie_phpsessid,vuser_cookie=$cookie___vuser" '; + + +access_log /home/wwwlogs/hicrew.log special_main; + +``` + + + +#### CPU 高,负载高,访问慢(没有数据库) + +- **记录负载开始升高的时间** +- 常见场景 + - 虚拟机所在的宿主机资源瓶颈,多个虚拟机竞争资源 + - 定时任务大量的任务并发 + - 消息、请求堆积后恢复时的瞬时流量引起 + - 持久化任务引起 + - 更多可以看这篇:[线上异常排查总结](https://blog.csdn.net/freeiceflame/article/details/78006812) +- 系统层面 + - 查看负载、CPU、内存、上线时间、高资源进程 PID:`htop` + - 查看磁盘使用情况:`df -h` + - 查看磁盘当前情况:`iostat -x -k 3 3`。如果发现当前磁盘忙碌,则查看是哪个 PID 在忙碌:`iotop -o -P -k -d 5` + - 查看 PID 具体在写什么东西:`lsof -p PID` + - 查看系统日志:`tail -400f /var/log/messages` + - 查看简化线程树:`pstree -a >> /opt/pstree-20180915.log` + - 其他机子 ping(多个地区 ping),看下解析 IP 与网络丢包 + - 查看网络节点情况:`traceroute www.youmeek.com` + - `ifconfig` 查看 dropped 和 error 是否在不断增加,判断网卡是否出现问题 + - `nslookup` 命令查看 DNS 是否可用 + - 如果 nginx 有安装:http_stub_status_module 模块,则查看当前统计 + - 查看 TCP 和 UDP 应用 + - `netstat -ntlp` + - `netstat -nulp` + - 统计当前连接的一些状态情况:`netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn` + - 查看每个 ip 跟服务器建立的连接数:`netstat -nat|awk '{print$5}'|awk -F : '{print$1}'|sort|uniq -c|sort -rn` + - 查看与后端应用端口连接的有多少:`lsof -i:8080|grep 'TCP'|wc -l` + - 跟踪程序(按 `Ctrl + C` 停止跟踪):`strace -tt -T -v -f -e trace=file -o /opt/strace-20180915.log -s 1024 -p PID` + - 看下谁在线:`w`,`last` + - 看下执行了哪些命令:`history` +- 程序、JVM 层面 + - 保存、查看 Nginx 程序 log + - 通过 GoAccess 分析 log + - 保存、查看 Java 程序 log + - 使用内置 tomcat-manager 监控配置,或者使用类似工具:psi-probe + - 使用 `ps -ef | grep java`,查看进程 PID + - 根据高 CPU 的进程 PID,查看其线程 CPU 使用情况:`top -Hp PID`,找到占用 CPU 资源高的线程 PID + - 保存堆栈情况:`jstack -l PID >> /opt/jstack-tomcat1-PID-20180917.log` + - 把占用 CPU 资源高的线程十进制的 PID 转换成 16 进制:`printf "%x\n" PID`,比如:`printf "%x\n" 12401` 得到结果是:`3071` + - 在刚刚输出的那个 log 文件中搜索:`3071`,可以找到:`nid=0x3071` + - 使用 `jstat -gc PID 10000 10`,查看gc情况(截图) + - 使用 `jstat -gccause PID`:额外输出上次GC原因(截图) + - 使用 `jstat -gccause PID 10000 10`:额外输出上次GC原因,收集 10 次,每隔 10 秒 + - 使用 `jmap -dump:format=b,file=/opt/dumpfile-tomcat1-PID-20180917.hprof PID`,生成堆转储文件 + - 使用 jhat 或者可视化工具(Eclipse Memory Analyzer 、IBM HeapAnalyzer)分析堆情况。 + - 结合代码解决内存溢出或泄露问题。 + - 给 VM 增加 dump 触发参数:`-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/tomcat-1.hprof` + +#### 一次 JVM 引起的 CPU 高排查 + +- 使用 `ps -ef | grep java`,查看进程 PID + - 根据高 CPU 的进程 PID,查看其线程 CPU 使用情况:`top -Hp PID`,找到占用 CPU 资源高的线程 TID + - 也可以用:`ps -mp PID -o THREAD,tid,time` +- 保存堆栈情况:`jstack -l TID >> /opt/jstack-tomcat1-TID-20181017.log` +- 把占用 CPU 资源高的线程十进制的 TID 转换成 16 进制:`printf "%x\n" TID`,比如:`printf "%x\n" 12401` 得到结果是:`3071` +- 在刚刚输出的那个 log 文件中搜索:`3071`,可以找到:`nid=0x3071` +- 也可以在终端中直接看:`jstack TID |grep 十六进制线程 -A 30`,此时如果发现如下: + +``` +"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007fd0ac01f000 nid=0x66f runnable +``` + +- 这种情况一般是 heap 设置得过小,而又要频繁分配对象;二是内存泄露,对象一直不能被回收,导致 CPU 占用过高 +- 使用:`jstat -gcutil PID 3000 10`: +- 正常情况结果应该是这样的: + +``` +S0 S1 E O M CCS YGC YGCT FGC FGCT GCT +0.00 0.00 67.63 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.68 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.68 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.68 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.68 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.68 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.68 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.68 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.71 38.09 78.03 68.82 124 0.966 5 0.778 1.744 +0.00 0.00 67.71 38.09 78.03 68.82 124 0.966 5 0.778 1.744 + +``` + +- S0:SO 当前使用比例 +- S1:S1 当前使用比例 +- E:**Eden 区使用比例(百分比)(异常的时候,这里可能会接近 100%)** +- O:**old 区使用比例(百分比)(异常的时候,这里可能会接近 100%)** +- M:**Metaspace 区使用比例(百分比)(异常的时候,这里可能会接近 100%)** +- CCS:压缩使用比例 +- YGC:年轻代垃圾回收次数 +- FGC:老年代垃圾回收次数 +- FGCT:老年代垃圾回收消耗时间(单位秒) +- GCT:垃圾回收消耗总时间(单位秒) +- **异常的时候每次 Full GC 时间也可能非常长,每次时间计算公式=FGCT值/FGC指)** +- `jmap -heap PID`,查看具体占用量是多大 +- 使用 `jmap -dump:format=b,file=/opt/dumpfile-tomcat1-PID-20180917.hprof PID`,生成堆转储文件(如果设置的 heap 过大,dump 下来会也会非常大) + - 使用 jhat 或者可视化工具(Eclipse Memory Analyzer 、IBM HeapAnalyzer)分析堆情况。 + - 一般这时候就只能根据 jhat 的分析,看源码了 +- 这里有几篇类似经历的文章推荐给大家: + - [三个神奇bug之Java占满CPU](http://luofei.me/?p=197) + - [CPU 负载过高问题排查](http://zhouyun.me/2017/10/24/cpu_load_issue/) + + +#### CPU 低,负载高,访问慢(带数据库) + +- 基于上面,但是侧重点在于 I/O 读写,以及是否有 MySQL 死锁,或者挂载了 NFS,而 NFS Server 出现问题 +- mysql 下查看当前的连接数与执行的sql 语句:`show full processlist;` +- 检查慢查询日志,可能是慢查询引起负载高,根据配置文件查看存放位置:`log_slow_queries` +- 查看 MySQL 设置的最大连接数:`show variables like 'max_connections';` + - 重新设置最大连接数:`set GLOBAL max_connections=300` + + + + +## 参考资料 + +- +- +- +- +- +- +- +- +- +- + + + + diff --git a/other.md b/markdown-file/other.md similarity index 100% rename from other.md rename to markdown-file/other.md diff --git a/markdown-file/shell-safe-rm.md b/markdown-file/shell-safe-rm.md new file mode 100644 index 00000000..d95e2539 --- /dev/null +++ b/markdown-file/shell-safe-rm.md @@ -0,0 +1,59 @@ +# 安装的 rm(删除) + +## 由来 + +- 我们都知道 `rm -rf` 是一个危险的操作,所以我们应该尽可能养成一个不要 rm 的习惯,而是 mv。 + +## 设置 + +- 创建一个用来存放要被我们删除的文件夹存放地:`cd $home && mkdir .trash` +- 赋予最高权限(个人习惯):`chmod 777 .trash` +- 如果你使用 bash,你需要修改你的 home 目录下的:`.bashrc` +- 我使用的是 zsh,所以我修改:`vim .zshrc`,在文件的最后面增加下面内容: + +``` +# rm transform +function rm() { + # garbage collect + now=$(date +%s) + for s in $(ls --indicator-style=none $HOME/.trash/) ;do + dir_name=${s//_/-} + dir_time=$(date +%s -d $dir_name) + # if big than one month then delete + if [[ 0 -eq dir_time || $(($now - $dir_time)) -gt 2592000 ]] ;then + echo "Trash " $dir_name " has Gone " + /bin/rm $s -rf + fi + done + + # add new folder + prefix=$(date +%Y_%m_%d) + hour=$(date +%H) + mkdir -p $HOME/.trash/$prefix/$hour + if [[ -z $1 ]] ;then + echo 'Missing Args' + return + fi + echo "Hi, Trashing" $1 "to /root/.trash" + mv $1 $HOME/.trash/$prefix/$hour +} +``` + +- 刷新配置:`source ~/.zshrc` +- 然后断开终端,重新连接 +- 此时如果你使用:`rm -rf a.txt` 会出现这样的提示: + +``` +Hi, Trashing -rf to /root/.trash +mv: invalid option -- 'r' +Try 'mv --help' for more information. +``` + +- 现在我们删除一个测试文件:`rm a.txt`,会事显示:`Hi, Trashing a.txt to /root/.trash` +- 因为我们上面的 shell 每次触发 rm 明白的时候都会去删除一个月前的目录,所以就不需要定时器来删除 .trash 里面的文件了。 +- 如果你要强制删除,清空 .trash 目录,可以使用真正的 rm 命令:`/usr/bin/rm -rf ~/.trash/*` + + +## 资料 + +- diff --git a/markdown-file/speedtest.md b/markdown-file/speedtest.md new file mode 100644 index 00000000..2bf84c18 --- /dev/null +++ b/markdown-file/speedtest.md @@ -0,0 +1,29 @@ +# 终端测速 + + +- 目前大家主推这个项目: +- 用起来也比较简单,Python 2 ~ 3 都支持。 + +## 简单安装方式 + +- 命令:`pip install speedtest-cli` +- 官网还介绍了其他很多安装使用方式,大家可以自行看下。 + +## 运行 + +- 命令:`speedtest-cli` +- 结果如下: + +``` +Retrieving speedtest.net configuration... +Testing from China Telecom Guangdong (113.67.181.234)... +Retrieving speedtest.net server list... +Selecting best server based on ping... +Hosted by CTM Internet Services (Macau) [106.48 km]: 64.783 ms +Testing download speed................................................................................ +Download: 1.05 Mbit/s +Testing upload speed................................................................................................ +Upload: 2.28 Mbit/s +``` + + diff --git a/ubuntu-settings/Network-Settings.md b/markdown-file/ubuntu-settings/Network-Settings.md similarity index 100% rename from ubuntu-settings/Network-Settings.md rename to markdown-file/ubuntu-settings/Network-Settings.md diff --git a/ubuntu-settings/Ubuntu-Create-Desktop.md b/markdown-file/ubuntu-settings/Ubuntu-Create-Desktop.md similarity index 71% rename from ubuntu-settings/Ubuntu-Create-Desktop.md rename to markdown-file/ubuntu-settings/Ubuntu-Create-Desktop.md index fb5bdedf..475babec 100644 --- a/ubuntu-settings/Ubuntu-Create-Desktop.md +++ b/markdown-file/ubuntu-settings/Ubuntu-Create-Desktop.md @@ -2,16 +2,16 @@ ## 创建图标文件 -- 我们建设以创建 Eclipse 程序图标为例 +- 我们建设以创建 pycharm 程序图标为例 - 进入图标存放目录|:`cd /usr/share/applications` -- 创建文件并编辑:`sudo gedit eclipse.desktop` +- 创建文件并编辑:`sudo gedit pycharm.desktop` ``` ini [Desktop Entry] -Name=eclipse -Name[zh_CN]=eclipse -Comment=eclipse Client -Exec=/usr/programa/tools/eclipse/eclipse -Icon=/usr/programa/tools/eclipse/icon.xpm +Name=Pycharm +Name[zh_CN]=Pycharm +Comment=Pycharm3:The Python IDE +Exec=/pycharm-community-2017.1.1/bin/pycharm.sh +Icon=/pycharm-community-2017.1.1/bin/pycharm.png Terminal=false Type=Application Categories=Application; @@ -23,7 +23,7 @@ StartupNotify=true - Comment 为说明。 - Exec 为程序执行位置 - Icon 为图标所在路径 -- 最后,打开 Dash,在顶部搜索框搜索 **eclipse**,此时你应该能搜到它,先单击试一下看能不能打开,如果可以打开,拖到该图标启动器上,下次就可以直接从启动器打开了 +- 最后,打开 Dash,在顶部搜索框搜索 **pycharm**,此时你应该能搜到它,先单击试一下看能不能打开,如果可以打开,拖到该图标启动器上,下次就可以直接从启动器打开了 ## 资料 diff --git a/ubuntu-settings/Ubuntu-Extra-Packages.md b/markdown-file/ubuntu-settings/Ubuntu-Extra-Packages.md similarity index 100% rename from ubuntu-settings/Ubuntu-Extra-Packages.md rename to markdown-file/ubuntu-settings/Ubuntu-Extra-Packages.md diff --git a/ubuntu-settings/Ubuntu-Popular-Settings.md b/markdown-file/ubuntu-settings/Ubuntu-Popular-Settings.md similarity index 100% rename from ubuntu-settings/Ubuntu-Popular-Settings.md rename to markdown-file/ubuntu-settings/Ubuntu-Popular-Settings.md diff --git a/markdown-file/ubuntu-settings/Ubuntu-UI.md b/markdown-file/ubuntu-settings/Ubuntu-UI.md new file mode 100644 index 00000000..2471042e --- /dev/null +++ b/markdown-file/ubuntu-settings/Ubuntu-UI.md @@ -0,0 +1,40 @@ + + +## Ubuntu 常见桌面环境方案 + +- [GNOME](https://www.gnome.org/) +- [KDE](https://www.kde.org/) +- [Unity8](https://ubports.com/zh_CN/blog/1/post/unity8-on-the-desktop-95) +- MATE +- Cinnamon +- Lxde +- Xfce + +## Ubuntu 18.04 桌面环境方案 + +- 使用 GNOME + +## Ubuntu 16.04 桌面环境方案 + +- 使用 Unity + +------------------------------------------------------------ + +## GUI 工具包 + +- [GTK](https://www.gtk.org/) +- [Qt](https://www.qt.io/) + +------------------------------------------------------------ + +## 常见桌面环境方案 与 GUI 工具包关系 + +- GNOME、LXDE、Xfce 使用 GTK 工具包 +- KDE、Unity8 使用 Qt 工具包 + + +## 资料 + +- [自由之选:七大顶尖 Linux 桌面环境比拼](https://linux.cn/article-6021-1.html) +- [自由奔放的 Linux (3)—— Gnome 与 KDE](http://blog.sciencenet.cn/blog-530833-540604.html) +- [自由奔放的 Linux (2) ——Ubuntu 与 Fedora](http://blog.sciencenet.cn/home.php?mod=space&uid=530833&do=blog&id=540366) diff --git a/ubuntu-settings/ubuntu-settings-toc.md b/markdown-file/ubuntu-settings/ubuntu-settings-toc.md similarity index 81% rename from ubuntu-settings/ubuntu-settings-toc.md rename to markdown-file/ubuntu-settings/ubuntu-settings-toc.md index 1b320721..2c437314 100644 --- a/ubuntu-settings/ubuntu-settings-toc.md +++ b/markdown-file/ubuntu-settings/ubuntu-settings-toc.md @@ -2,13 +2,7 @@ - [Ubuntu 源设置](Ubuntu-Extra-Packages.md) - [Ubuntu 给 Dash 添加程序图标](Ubuntu-Create-Desktop.md) - [Ubuntu 常用设置](Ubuntu-Popular-Settings.md) -- []() -- []() -- []() -- []() -- []() -- []() -- []() +- [Ubuntu 常见桌面环境方案](Ubuntu-UI.md) diff --git a/markdown-file/wrk-Install-And-Settings.md b/markdown-file/wrk-Install-And-Settings.md new file mode 100644 index 00000000..f6b7c67f --- /dev/null +++ b/markdown-file/wrk-Install-And-Settings.md @@ -0,0 +1,65 @@ +# wrk 安装和配置 + + +## wrk 说明 + +- wrk 相对于 ab 来说最大的优点是它支持多线程,可以有更大的并发量 + + +## 安装 + +- CentOS 7.4 +- 官网说明: + +``` +# 安装工具包的时候差不多有 90 个左右的子工具 +sudo yum groupinstall 'Development Tools' +sudo yum install -y openssl-devel git +git clone --depth=1 https://github.com/wg/wrk.git wrk +cd wrk +make +# move the executable to somewhere in your PATH +sudo cp wrk /usr/local/bin +``` + +- 查看帮助:`wrk --help` + +## 使用 + +- 启用 10 个线程,每个线程发起 100 个连接,持续 30 秒:`wrk -t10 -c100 -d30s http://www.baidu.com` +- 最终报告: + +``` +Running 30s test @ http://www.baidu.com + 5 threads and 5 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 44.59ms 17.41ms 331.91ms 95.66% + Req/Sec 23.11 5.77 30.00 57.04% + 3439 requests in 30.03s, 50.47MB read + Socket errors: connect 0, read 10, write 0, timeout 0 +Requests/sec: 114.52 +Transfer/sec: 1.68MB +``` + +#### 使用 lua 脚本(发送一个 post 请求) + +- 创建:`vim /opt/post-wrk.lua` + +``` +wrk.method = "POST" +wrk.body = "hms_user_id=222222&routing_key=ad.sys_user.add" +wrk.headers["Content-Type"] = "application/x-www-form-urlencoded" +``` + +- 测试:`wrk -t10 -c100 -d15s --script=/opt/post-wrk.lua --latency http://127.0.0.1:9090/websocket/api/send-by-user-id` + + +## 其他说明 + +- wrk 使用的是 HTTP/1.1,缺省开启的是长连接 +- 要测试短连接:`wrk -H "Connection: Close" -c 100 -d 10 http://domain/path` + +## 资料 + +- +-