获取python3 wget https://www.python.org/ftp/python/3.7.3/Python-3.7.3.tgz安装python3mkdir -p /server/python3 tar -zxvf Python-3.7.3.tgz cd Python-3.7.3 # 安装依赖 yum -y install zlib zlib-devel yum -y install bzip2 bzip2-devel yum -y install ncurses ncurses-devel yum -y install readline readline-devel yum -y install openssl openssl-devel yum -y install openssl-static yum -y install xz lzma xz-devel yum -y install sqlite sqlite-devel yum -y install gdbm gdbm-devel yum -y install tk tk-devel yum -y install libffi libffi-devel ./configure --prefix=/server/python3 --enable-shared CFLAGS=-fPIC make make install # 创建软链接 ln -s /server/python3/bin/python3.7 /usr/bin/python3 # 查看版本 python3 -V 如图所示安装成功错误处理如出现如下错误python3: error while loading shared libraries: libpython3.7m.so.1.0:cannot open shared object file: No such file or directoryldd python3 名为libpython3.7m.so.1.0的动态链接库找不到，找到它的路径，加载进去即可 find / -iname 'libpython3.7m.so.1.0' # 配置文件的名字可以随便起，起的有意义比较好 vim /etc/ld.so.conf.d/python3.conf # 将路径添加进去 然后保存 /server/python/lib # 加载动态链接库 ldconfig # 查看依赖 已经全部找到了 ldd python3关于ldconfigldconfig动态链接库管理命令ldconfig命令 的用途主要是在默认搜寻目录/lib和/usr/lib以及动态库配置文件/etc/ld.so.conf内所列的目录下，搜索出可共享的动态链接库（格式如lib.so）,进而创建出动态装入程序(ld.so)所需的连接和缓存文件。缓存文件默认为/etc/ld.so.cache，此文件保存已排好序的动态链接库名字列表，为了让动态链接库为系统所共享，需运行动态链接库的管理命令ldconfig，此执行程序存放在/sbin目录下。ldconfig通常在系统启动时运行，而当用户安装了一个新的动态链接库时，就需要手工运行这个命令。ldconfig几个需要注意的地方：往/lib和/usr/lib里面加东西，是不用修改/etc/ld.so.conf的，但是完了之后要调一下ldconfig，不然这个library会找不到。想往上面两个目录以外加东西的时候，一定要修改/etc/ld.so.conf，然后再调用ldconfig，不然也会找不到。比如安装了一个mysql到/usr/local/mysql，mysql有一大堆library在/usr/local/mysql/lib下面，这时就需要在/etc/ld.so.conf下面加一行/usr/local/mysql/lib，保存过后ldconfig一下，新的library才能在程序运行时被找到。如果想在这两个目录以外放lib，但是又不想在/etc/ld.so.conf中加东西（或者是没有权限加东西）。那也可以，就是export一个全局变量LD_LIBRARY_PATH，然后运行程序的时候就会去这个目录中找library。一般来讲这只是一种临时的解决方案，在没有权限或临时需要的时候使用。ldconfig做的这些东西都与运行程序时有关，跟编译时一点关系都没有。编译的时候还是该加-L就得加，不要混淆了。总之，就是不管做了什么关于library的变动后，最好都ldconfig一下，不然会出现一些意想不到的结果。不会花太多的时间，但是会省很多的事。再有，诸如libdb-4.3.so文件头中是会含有库名相关的信息的（即含“libdb-4.3.so”，可用strings命令察看），因此仅通过修改文件名以冒充某已被识别的库（如libdb-4.8.so）是行不通的。为此可在编译库的Makefile中直接修改配置信息，指定特别的库名。
Nginx安装文档看 这里基础配置详解nginx.conf 配置结构... #全局块 events { #events块 ... } http #http块 { ... #http全局块 server #server块 { ... #server全局块 location [PATTERN] #location块 { ... } location [PATTERN] { ... } } server { ... } ... #http全局块 } main全局块：配置影响nginx全局的指令。一般有运行nginx服务器的用户组，nginx进程pid存放路径，日志存放路径，配置文件引入，允许生成worker process数等。events块：配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数，选取哪种事件驱动模型处理连接请求，是否允许同时接受多个网路连接，开启多个网络连接序列化等。http块：可以嵌套多个server，配置代理，缓存，日志定义等绝大多数功能和第三方模块的配置。如文件引入，mime-type定义，日志自定义，是否使用sendfile传输文件，连接超时时间，单连接请求数等。server块：配置虚拟主机的相关参数，一个http中可以有多个server。location块：配置请求的路由，以及各种页面的处理情况。不同模块指令关系：server继承main；location继承server；upstream既不会继承指令也不会被继承，它有自己的特殊指令，不需要在其他地方的应用nginx内置全局变量变量名功能$host请求信息中的 Host，如果请求中没有Host行，则等于设置的服务器名$request_method客户端请求类型，如 GET、 POST$remote_addr客户端的 IP地址$args请求中的参数$content_length请求头中的 Content-length字段$http_user_agent客户端agent信息$http_cookie客户端cookie信息$remote_addr客户端的IP地址$remote_port客户端的端口$server_protocol请求使用的协议，如HTTP/1.0、·HTTP/1.1$server_addr服务器地址$server_name服务器名称$server_port服务器的端口号nginx.conf 基本配置模板每个指令必须有分号结束########### 每个指令必须有分号结束。################# #配置用户或者组，默认为nobody nobody。 user www www; #工作的进程数，系统会根据服务器自动生成 worker_processes 2; #指定nginx进程运行文件存放地址 pid /nginx/pid/nginx.pid; #制定错误日志路径，级别。这个设置可以放入全局块，http块，server块，级别依次为：debug|info|notice|warn|error|crit|alert|emerg error_log log/error.log debug; #工作模式及连接数上限 events { #设置网路连接序列化，防止惊群现象发生，默认为on accept_mutex on; #设置一个进程是否同时接受多个网络连接，默认为off multi_accept on; #事件驱动模型，select|poll|kqueue|epoll|resig|/dev/poll|eventport use epoll; #单个work进程允许的最大连接数，默认为512 worker_connections 1024; } #http服务器 http { #文件扩展名与文件类型映射表。设定mime类型(邮件支持类型),类型由mime.types文件定义 include mime.types; #默认文件类型，默认为text/plain default_type application/octet-stream; #取消服务访问日志 #access_log off; #自定义日志格式 log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #设置访问日志路径和格式。"log/"该路径为nginx日志的相对路径，mac下是/usr/local/var/log/。combined为日志格式的默认值 access_log log/access.log myFormat; rewrite_log on; #允许sendfile方式传输文件，默认为off，可以在http块，server块，location块。（sendfile系统调用不需要将数据拷贝或者映射到应用程序地址空间中去） sendfile on; #每个进程每次调用传输数量不能大于设定的值，默认为0，即不设上限。 sendfile_max_chunk 100k; #连接超时时间，默认为75s，可以在http，server，location块。 keepalive_timeout 65; #gzip压缩开关 gzip on; tcp_nodelay on; #设定实际的服务器列表 upstream mysvr1 { server 127.0.0.1:7878; server 192.168.10.121:3333 backup; #热备(其它所有的非backup机器down或者忙的时候，请求backup机器)) } #weigth参数表示权值，权值越高被分配到的几率越大 upstream mysvr2 { server 192.168.1.11:80 weight=5; server 192.168.1.12:80 weight=1; server 192.168.1.13:80 weight=6; } #每个请求按访问ip的hash结果分配，这样每个访客固定访问一个后端服务器，可以解决session的问题 upstream https-svr { ip_hash; server 192.168.1.11:90; server 192.168.1.12:90; } error_page 404 https://www.baidu.com; #错误页 #HTTP服务器 # 静态资源一般放在nginx所在主机 server { listen 80; #监听HTTP端口 server_name 127.0.0.1; #监听地址 keepalive_requests 120; #单连接请求上限次数 set $doc_root_dir "/Users/doing/IdeaProjects/edu-front-2.0"; #设置server里全局变量 index index.php index.html; #定义首页索引文件的名称 location ~*^.+$ { #请求的url过滤，正则匹配，~为区分大小写，~*为不区分大小写。 root $doc_root_dir; #静态资源根目录 proxy_pass http://mysvr1; #请求转向“mysvr1”定义的服务器列表 deny 127.0.0.1; #拒绝的ip allow 172.18.5.54; #允许的ip } } #http server { listen 80; server_name www.helloworld.com; #监听基于域名的虚拟主机。可有多个，可以使用正则表达式和通配符 charset utf-8; #编码格式 set $static_root_dir "/Users/doing/static"; location /app1 { #反向代理的路径（和upstream绑定），location后面设置映射的路径 proxy_pass http://zp_server1; } location /app2 { proxy_pass http://zp_server2; } location ~ ^/(images|javascript|js|css|flash|media|static)/ { #静态文件，nginx自己处理 root $static_root_dir; expires 30d; #静态资源过时间30天 } location ~ /\.ht { #禁止访问 .htxxx 文件 deny all; } location = /do_not_delete.html { #直接简单粗暴的返回状态码及内容文本 return 200 "hello."; } # 指定某些路径使用https访问(使用正则表达式匹配路径+重写uri路径) location ~* /http* { #路径匹配规则：如localhost/http、localhost/httpsss等等 #rewrite只能对域名后边的除去传递的参数外的字符串起作用，例如www.c.com/proxy/html/api/msg?method=1&para=2只能对/proxy/html/api/msg重写。 #rewrite 规则 定向路径 重写类型; #rewrite后面的参数是一个简单的正则。$1代表正则中的第一个()。 #$host是nginx内置全局变量，代表请求的主机名 #重写规则permanent表示返回301永久重定向 rewrite ^/(.*)$ https://$host/$1 permanent; } #错误处理页面（可选择性配置） #error_page 404 /404.html; #error_page 500 502 503 504 /50x.html; #以下是一些反向代理的配置(可选择性配置) #proxy_redirect off; #proxy_set_header Host $host; #proxy_set_header用于设置发送到后端服务器的request的请求头 #proxy_set_header X-Real-IP $remote_addr; #proxy_set_header X-Forwarded-For $remote_addr; #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP #proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时) #proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时) #proxy_read_timeout 90; #连接成功后，后端服务器响应时间(代理接收超时) #proxy_buffer_size 4k; #设置代理服务器（nginx）保存用户头信息的缓冲区大小 #proxy_buffers 4 32k; #proxy_buffers缓冲区，网页平均在32k以下的话，这样设置 #proxy_busy_buffers_size 64k; #高负荷下缓冲大小（proxy_buffers*2） #proxy_temp_file_write_size 64k; #设定缓存文件夹大小，大于这个值，将从upstream服务器传 #client_max_body_size 10m; #允许客户端请求的最大单文件字节数 #client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数 } #https #(1)HTTPS的固定端口号是443，不同于HTTP的80端口； #(2)SSL标准需要引入安全证书，所以在 nginx.conf 中你需要指定证书和它对应的 key server { listen 443; server_name www.hellohttps1.com www.hellohttps2.com; set $geek_web_root "/Users/doing/IdeaProjects/backend-geek-web"; ssl_certificate /usr/local/etc/nginx/ssl-key/ssl.crt; #ssl证书文件位置(常见证书文件格式为：crt/pem) ssl_certificate_key /usr/local/etc/nginx/ssl-key/ssl.key; #ssl证书key位置 location /passport { send_timeout 90; proxy_connect_timeout 50; proxy_send_timeout 90; proxy_read_timeout 90; proxy_pass http://https-svr; } location ~ ^/(res|lib)/ { root $geek_web_root; expires 7d; #add_header用于为后端服务器返回的response添加请求头，这里通过add_header实现CROS跨域请求服务器 add_header Access-Control-Allow-Origin *; } #ssl配置参数（选择性配置） ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; } #配置访问控制：每个IP一秒钟只处理一个请求，超出的请求会被delayed #语法：limit_req_zone $session_variable zone=name:size rate=rate (为session会话状态分配一个大小为size的内存存储区，限制了每秒（分、小时）只接受rate个IP的频率) limit_req_zone $binary_remote_addr zone=req_one:10m rate=1r/s nodelay; location /pay { proxy_set_header Host $http_host; proxy_set_header X-Real_IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #访问控制：limit_req zone=name [burst=number] [nodelay]; limit_req zone=req_one burst=5; #burst=5表示超出的请求(被delayed)如果超过5个，那些请求会被终止（默认返回503） proxy_pass http://mysvr1; } #可以把子配置文件放到/usr/local/etc/nginx/servers/路径下，通过include引入 include /usr/local/etc/nginx/servers/*.conf; } 常用功能php文件解析# fastcgi方式php文件解析 server{ listen 81; location / { root /server/www/htdocs/p5; index index.php index.html; allow all; } location ~ \.php$ { error_log logs/test.logss; root /server/www/htdocs/p5; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; #fastcgi_param SCRIPT_FILENAME /server/www/htdocs/p5/$fastcgi_script_name; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } 另一种方式解析# 在linux中 php-fpm支持以套接字的形式绑定，在高并发的时候性能更好 # 1. 修改php-fpm.conf文件 listen = 127.0.0.1:9000 # 修改为 listen = /dev/shm/phpfpm.sock # 这里的路径可以随便写，注意，需要给予nginx用户的读写权限 # /dev/shm这个目录比较特殊 不在硬盘中，在内存中，读取速度更快 # 重启php-fpm服务 # 修改nginx.php fastcgi_pass 127.0.0.1:9000; # 修改为 fastcgi_pass unix:/dev/shm/phpfpm.sock; # 重启nginx 即可防盗链设置 location ~* \.(gif|jpg|png|jpeg)$ { expires 30d; #设置资源有效期 valid_referers a.com *.net; # 有效的域名 这种方式图片也无法被直接访问 必须在域名下才能访问 # valid_referers none blocked a.com *.net; # 加上 none blocked 图片可以被直接访问 if ($invalid_referer) { rewrite ^/ http://xxx.xx; #return 404; } }允许跨域 # location 作用域 add_header Access-Control-Allow-Origin *;访问控制location / { allow xx.xx.xx.xx; # allow all; deny all; deny xx.xx.xx.xx; }请求过滤根据状态码过滤error_page 500 501 502 503 504 506 /50x.html; location = /50x.html { #将跟路径改编为存放html的路径。 root /root/static/html; }根据URL名称过滤，精准匹配URL，不匹配的URL全部重定向到主页。location / { rewrite ^.*$ /index.html redirect; }根据请求类型过滤。if ( $request_method !~ ^(GET|POST|HEAD)$ ) { return 403; }gzip配置GZIP是规定的三种标准HTTP压缩格式之一。目前绝大多数的网站都在使用 GZIP传输 HTML、 CSS、 JavaScript 等资源文件。对于文本文件， GZip的效果非常明显，开启后传输所需流量大约会降至 1/4~1/3。并不是每个浏览器都支持 gzip的，如何知道客户端是否支持 gzip呢，请求头中的 Accept-Encoding来标识对压缩的支持。启用 gzip同时需要客户端和服务端的支持，如果客户端支持 gzip的解析，那么只要服务端能够返回 gzip的文件就可以启用 gzip了,我们可以通过 gzip的配置来让服务端支持 gzip。下面的 respone中 content-encoding:gzip，指服务端开启了 gzip的压缩方式。gzip on; gzip_http_version 1.1; gzip_comp_level 5; gzip_min_length 1000; gzip_types text/csv text/xml text/css text/plain text/javascript application/javascript application/x-javascript application/json application/xml; gzip开启或者关闭 gzip模块默认值为 off可配置为 on/offgziphttpversion启用 GZip 所需的 HTTP 最低版本默认值为 HTTP/1.1这里为什么默认版本不是 1.0呢？HTTP 运行在 TCP 连接之上，自然也有着跟 TCP 一样的三次握手、慢启动等特性。启用持久连接情况下，服务器发出响应后让 TCP连接继续打开着。同一对客户/服务器之间的后续请求和响应可以通过这个连接发送。为了尽可能的提高 HTTP 性能，使用持久连接就显得尤为重要了。HTTP/1.1默认支持 TCP持久连接， HTTP/1.0 也可以通过显式指定 Connection:keep-alive来启用持久连接。对于 TCP持久连接上的 HTTP 报文，客户端需要一种机制来准确判断结束位置，而在HTTP/1.0中，这种机制只有 Content-Length。而在 HTTP/1.1中新增的Transfer-Encoding:chunked 所对应的分块传输机制可以完美解决这类问题。nginx同样有着配置 chunked的属性 chunked_transfer_encoding，这个属性是默认开启的。Nginx在启用了 GZip的情况下，不会等文件 GZip 完成再返回响应，而是边压缩边响应，这样可以显著提高 TTFB(TimeToFirstByte，首字节时间，WEB 性能优化重要指标)。这样唯一的问题是， Nginx开始返回响应时，它无法知道将要传输的文件最终有多大，也就是无法给出 Content-Length这个响应头部。所以，在 HTTP1.0中如果利用 Nginx启用了 GZip，是无法获得Content-Length的，这导致HTTP1.0中开启持久链接和使用 GZip只能二选一，所以在这里gzip_http_version默认设置为 1.1。gzipcomplevel压缩级别，级别越高压缩率越大，当然压缩时间也就越长（传输快但比较消耗cpu）。默认值为 1压缩级别取值为 1-9gzipminlength设置允许压缩的页面最小字节数，Content-Length小于该值的请求将不会被压缩默认值: 0当设置的值较小时，压缩后的长度可能比原文件大，建议设置 1000以上gzip_types要采用gzip压缩的文件类型( MIME类型)默认值: text/html(默认不压缩 js/ css)负载均衡设置Upstream指定后端服务器地址列表upstream balanceServer { server 10.1.22.33:12345; server 10.1.22.34:12345; server 10.1.22.35:12345; }在server中拦截响应请求，并将请求转发到Upstream中配置的服务器列表。server { server_name fe.server.com; listen 80; location /api { proxy_pass http://balanceServer; } } 上面的配置只是指定了nginx需要转发的服务端列表，并没有指定分配策略。nginx实现负载均衡的策略轮询策略默认情况下采用的策略，将所有客户端请求轮询分配给服务端。这种策略是可以正常工作的，但是如果其中某一台服务器压力太大，出现延迟，会影响所有分配在这台服务器下的用户。upstream balanceServer { server 10.1.22.33:12345; server 10.1.22.34:12345; server 10.1.22.35:12345; } 最小连接数策略将请求优先分配给压力较小的服务器，它可以平衡每个队列的长度，并避免向压力大的服务器添加更多的请求。upstream balanceServer { least_conn; server 10.1.22.33:12345; server 10.1.22.34:12345; server 10.1.22.35:12345; } 最快响应时间策略依赖于NGINX Plus，优先分配给响应时间最短的服务器。upstream balanceServer { fair; server 10.1.22.33:12345; server 10.1.22.34:12345; server 10.1.22.35:12345; }客户端ip绑定来自同一个ip的请求永远只分配一台服务器，有效解决了动态网页存在的session共享问题。upstream balanceServer { ip_hash; server 10.1.22.33:12345; server 10.1.22.34:12345; server 10.1.22.35:12345; }反向代理location / { proxy_pass http://127.0.0.1:9000; 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 REMOTE-HOST $remote_addr; # 持久化连接相关配置 proxy_connect_timeout 30s; proxy_read_timeout 86400s; proxy_send_timeout 30s; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; add_header X-Cache $upstream_cache_status; #expires 12h; }静态资源服务器location ~* \.(png|gif|jpg|jpeg)$ { root /root/static/; # 设置静态资源路径 autoindex on; # 显示目录结构 access_log off; # 关闭访问日志 expires 10h;# 设置过期时间为10小时 }匹配以 png|gif|jpg|jpeg为结尾的请求，并将请求转发到本地路径， root中指定的路径即nginx本地路径。同时也可以进行一些缓存的设置。
文档官网文档地址 http://nginx.org/en/docs/configure.html获取资源 wget wget http://nginx.org/download/nginx-1.16.0.tar.gz安装常用编译选项文件和权限--prefix=path定义 nginx 文件的安装路径。configure 的其他选项如果使用相对路径，那么以此路径为基础路径。(except for pathsto libraries sources)。nginx.conf 文件中的相对路径也以此为基础路径。默认--prefix=/usr/local/nginx--sbin-path=path设置 nginx 二进制程序的路径名，这个名字只在安装期间使用。 默认 --sbin-path=prefix/sbin/nginx--conf-path=path设置 nginx.conf 的路径。nginx 可在启动时手动以 -c file 参数指定其他配置文件。默认--conf-path=prefix/conf/nginx.conf--pid-path=path设置 nginx.pid 文件的路径。安装nginx之后，可在 nginx.conf 文件中使用 pid 指令修改该路径。默认--pid-path=prefix/logs/nginx.pid--error-log-path=path设置 nginx 错误日志的路径。安装nginx之后，可在 nginx.conf 文件中使用 error_log 指令修改该路径。默认--error-log-path=prefix/logs/error.log--http-log-path=path设置 nginx 访问日志的路径。安装nginx之后，可在 nginx.conf 文件中使用 access_log 指令修改该路径。默认--http-log-path=prefix/logs/access.log--user=name设置启动 worker 进程时所使用的非特权用户名。安装nginx之后，可在 nginx.conf 文件中使用 user指令修改用户名。默认 --user=nobody--group=name设置启动 worker 进程时所使用的非特权用户组名。安装nginx之后，可在 nginx.conf 文件中使用 group指令修改用户组名。默认 --group=nobody事件循环--with-select_module--without-select_module是否编译 select 模块。使用 select 模块可使 nginx 工作于 select() 模式。 如果 nginx不支持其他更合适的模块，如 kqueue, epoll 或者 /dev/poll，该模块被自动编译。--with-poll_module--without-poll_module是否编译 poll 模块。使用 poll 模块可使 nginx 工作于 poll() 模式。 如果 nginx 不支持其他更合适的模块，如kqueue, epoll 或者 /dev/poll，该模块被自动编译。可选模块--without-http_gzip_module不编译 gzip 压缩模块。压缩模块用于压缩 HTTP 响应报文。该模块的编译和运行依赖 zlib 库。--without-http_rewrite_module不编译 rewrite 模块。rewrite 模块用于重定向 HTTP 请求，也可以改写 HTTP 请求的 URI。该模块的编译和运行依赖PCRE 库。--without-http_proxy_module不编译代理模块--with-http_ssl_module编译 ssl 模块。ssl 模块使 nginx 支持 HTTPs 协议。该模块默认不编译。该模块的编译和运行依赖 OpenSSL 库。--with-pcre=path设置PCRE库源的路径。库分发（版本4.4-8.43）需要从PCRE站点下载并提取。其余由nginx的./configure和make完成。对于location指令中的正则表达式支持和ngx_http_rewrite_module模块，需要使用库。--with-pcre-jit编译 PCRE 库时，加入 “just-in-time compilation” 支持 (1.1.12, the pcre_jit directive)--with-zlib=path设置 zlib 库的源码路径。首先需要下载和解压 zlib 库。 要求 zlib 库的版本范围为 1.1.3 -1.2.8，设置之后，其余的就交给 ./configure 和 make 命令。gzip 压缩模块依赖 zlib 库。编译控制--with-cc-opt=parameters为 CFLAGS 变量设置额外的参数。比如 FreeBSD 下使用 PCRE 库，必须指定 --with-cc-opt="-I/usr/local/include"。 比如 希望增加 select() 支持的文件数，可指定：--with-cc-opt="-DFD_SETSIZE=2048"--with-ld-opt=parameters设置链接时的额外参数。比如，FreeBSD 使用 PCRE 库时，必须指定 --with-ld-opt="-L/usr/local/lib"。开始安装tar -zxvf nginx-1.16.0.tar.gz cd nginx-1.16.0 mkdir -p /server/nginx ./configure --prefix=/server/nginx \ --user=www \ --group=www \ --with-http_ssl_module \ --with-pcre=/server/source/pcre-8.41 make make install编写启动脚本vim /etc/init.d/nginxd #--------以下为脚本内容-------- #!/bin/sh # # nginx - this script starts and stops the nginx daemon # # chkconfig: 3 85 15 # description: NGINX is an HTTP(S) server, HTTP(S) reverse \ # proxy and IMAP/POP3 proxy server # processname: nginx # config: /server/nginx/conf/nginx.conf # config: /etc/sysconfig/nginx # pidfile: /server/nginx/logs/nginx.pid # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ "$NETWORKING" = "no" ] && exit 0 nginx="/server/nginx/sbin/nginx" prog=$(basename $nginx) NGINX_CONF_FILE="/server/nginx/conf/nginx.conf" [ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx lockfile=/server/nginx/logs/nginx.lock make_dirs() { # make required directories user=`$nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -` if [ -z "`grep $user /etc/passwd`" ]; then useradd -M -s /bin/nologin $user fi options=`$nginx -V 2>&1 | grep 'configure arguments:'` for opt in $options; do if [ `echo $opt | grep '.*-temp-path'` ]; then value=`echo $opt | cut -d "=" -f 2` if [ ! -d "$value" ]; then # echo "creating" $value mkdir -p $value && chown -R $user $value fi fi done } start() { [ -x $nginx ] || exit 5 [ -f $NGINX_CONF_FILE ] || exit 6 make_dirs echo -n $"Starting $prog: " daemon $nginx -c $NGINX_CONF_FILE retval=$? echo [ $retval -eq 0 ] && touch $lockfile return $retval } stop() { echo -n $"Stopping $prog: " killproc $prog -QUIT retval=$? echo [ $retval -eq 0 ] && rm -f $lockfile return $retval } restart() { configtest || return $? stop sleep 1 start } reload() { configtest || return $? echo -n $"Reloading $prog: " killproc $nginx -HUP RETVAL=$? echo } force_reload() { restart } configtest() { $nginx -t -c $NGINX_CONF_FILE } rh_status() { status $prog } rh_status_q() { rh_status >/dev/null 2>&1 } case "$1" in start) rh_status_q && exit 0 $1 ;; stop) rh_status_q || exit 0 $1 ;; restart|configtest) $1 ;; reload) rh_status_q || exit 7 $1 ;; force-reload) force_reload ;; status) rh_status ;; condrestart|try-restart) rh_status_q || exit 0 ;; *) echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}" exit 2 esac启动服务service nginxd start # 停止服务 service nginxd stop # 重启 service nginxd restart # 检测配置文件语法 service nginxd configtest添加开机自启chkconfig --add nginxd注意脚本中的# chkconfig: 3 85 15这一行注释不要删掉，chkconfig通过此参数来设置启动项启动服务设置可以参看 这里
php在apache服务器下运行方式主要有一下几种：模块化(效率最高)CGI方式(不推荐，效率低)FastCgiphpfpm1. 模块化方式在编译安装php的时候,增加--with-apxs2=/server/httpd/bin/apxs 选项，会自动生成php5_module。在http.conf文件中如下设置 # 加载模块 LoadModule php5_module modules/libphp5.so # 设置方式1 <FilesMatch "\.php$"> SetHandler application/x-httpd-php </FilesMatch> # 设置方式2 # 在<IfModule mime_module>中添加如下内容 AddType application/x-httpd-php .php 2.CGI方式CGI是通用网关接口协议的缩写，是一种通用的规范协议，与语言无关，编译安装的php在bin下会存在一个php-cgi，就是php自带的CGI接口程序设置如下# 加载模块 LoadModule alias_module modules/mod_alias.so LoadModule cgid_module modules/mod_cgid.so(linux) LoadModule cgi_module modules/mod_cgi.so(windows) LoadModule actions_module modules/mod_actions.so # 在安装好的php目录下的bin下复制php-cgi到 /server/www/cgi-bin # /server/www/cgi-bin 此目录是在安装apache的时候自动生成的，/server/www/是apaceh服务器的网页根目录 # 将安装好的php-cgi复制到有执行CGI程序权限的目录下 # 这个目录可以是任意目录，只要在配置中给权限就好，建议放在官方推荐的位置，根据安装位置的不同，默认的位置不同 cp /server/php56/bin/php-cgi /server/www/cgi-bin/ # 在http.conf文件中查找ScriptAlias，规定了CGI执行目录 ScriptAlias /cgi-bin/ "/server/www/cgi-bin" <Directory "/server/www/cgi-bin"> AllowOverride None Options All Require all granted </Directory> AddType application/x-httpd-php .php Action application/x-httpd-php /cgi-bin/php-cgi # application/x-httpd-php 可以自定义 扩展.php的Mime 3.FastCgi方式FastCgi是对CGI方式的一个优化，效率有显著提升php官网中的FastCgi安装说明 点我不过FastCgi的官网已经倒闭了....好在Apache提供了新的模块mod_fcgid来支持FastCgi的实现mod_fcgid官方文档地址 点我# 安装 mod_fcgid 模块 wget http://mirror.bit.edu.cn/apache//httpd/mod_fcgid/mod_fcgid-2.3.9.tar.gz tar -zxvf mod_fcgid-2.3.9.tar.gz cd mod_fcgid-2.3.9 APXS=/server/httpd/bin/apxs ./configure.apxs make make install 查看http.conf文件，会发现配置文件LoadModule最后面会自动加了一行 LoadModule fcgid_module modules/mod_fcgid.so # 这里是通用设置所有的.php文件都会被处理 # 不同的虚拟机还可以配置不同的php版本处理 <IfModule fcgid_module> # 初始化设置 # CGI进程的最大请求个数 FcgidInitialEnv PHP_FCGI_MAX_REQUESTS 1000 #fcgi每个进程的最大请求数要<= 上面的PHP_FCGI_MAX_REQUESTS 否则会出现请求完不成的问题 FcgidMaxRequestsPerProcess 1000 #php-cgi最大的进程数 FcgidMaxProcesses 5 #最大执行时间 FcgidIOTimeout 120 FcgidIdleTimeout 120 AddHandler fcgid-script .php <FilesMatch "\.php$"> Options ExecCgi FcgidWrapper /server/www/cgi-bin/php-cgi .php </FilesMatch> </IfModule> # 为虚拟机设置不同的php版本 # 注释掉上文中的FilesMatch容器 # 在虚拟机内添加如下设置 # 更改不同版本的cgi路径即可 <FilesMatch '\.php$'> Options ExecCgi FcgidWrapper /server/www/cgi-bin/php-cgi .php </FilesMatch> 4. php-fpm php fastcgi process manager该方式的本质还是FastCgi不过管理Cgi的工作由Apache变成了php，Apache只做转发工作该方式需要在编译安装的时候开启 --enable-fpm安装成功在安装目录下的sbin下会出现一个php-fpmphp-fpm方式 # 复制启动脚本到 启动目录 cp /server/source/php-5.6.38/sapi/fpm/init.d.php-fpm.in /etc/init.d/php-fpm56 # 复制配置文件到/etc下 # 默认的文件在安装路径下的etc中 cp /server/php56/etc/php-fpm.conf.default /etc/php-fpm56.conf # 修改php-fpm56.conf配置文件 默认参数基本不需要修改什么php-fpm调优参数设置参考 这里这里附上一份宝塔面板的php-fpm参数配置供参考[global] pid = /www/server/php/56/var/run/php-fpm.pid error_log = /www/server/php/56/var/log/php-fpm.log log_level = notice [www] listen = /tmp/php-cgi-56.sock listen.backlog = -1 listen.allowed_clients = 127.0.0.1 listen.owner = www listen.group = www listen.mode = 0666 user = www group = www pm = dynamic pm.status_path = /phpfpm_56_status pm.max_children = 80 pm.start_servers = 15 pm.min_spare_servers = 15 pm.max_spare_servers = 80 request_terminate_timeout = 100 request_slowlog_timeout = 30 slowlog = var/log/slow.log # 启动php-fpm /etc/init.d/php-fpm56 start # 修改http.conf文件 # 需要代理模块 LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so ProxyPass '/status' fcgi://127.0.0.1:9000 # 这个是设置访问/status 查看当前php-fpm的工作情况 实际生产环境中 需要把这个屏蔽掉 ProxyRequests Off ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/server/www/htdocs/p5/$1 # 这里的目录要和访问的文件实际所在路径完全一致 相关文章apache安装看 这里apache配置看 这里
Apache安装参看此文章 https://xbug.top/index.php/archives/195.html基础命令# 启动服务 /server/httpd/bin/apachectl -k start # 立即停止 kill -TERM `cat /server/httpd/logs/httpd.pid` # 立即停止2 /server/httpd/bin/apachectl -k stop # 优雅重启 # 此方式重启不会停止服务 # 在重启过程中确保有适当数量的进程和线程以响应客户端的请求 /server/httpd/bin/apachectl -k graceful # 立即重启 /server/httpd/bin/apachectl -k restart # 优雅停止 # 进程会完成现有的服务再退出，如果没有服务，立刻退出 /server/httpd/bin/apachectl -k graceful-stop # 检测配置文件语法错误 /server/httpd/bin/apachectl -t 配置文件详解主配置文件httpd.conf详解# 常用配置及配置详解 # apache安目录，编译时指定，不指定路径时默认路径为/usr/local/apache2 ServerRoot "/server/httpd" # 主站监听端口，可以监听多个端口 #Listen 12.34.56.78:80 # Listen 443 Listen 80 # 模块动态加载，这里只列举几个用到的模块 # 别名 LoadModule alias_module modules/mod_alias.so # url重写 LoadModule rewrite_module modules/mod_rewrite.so # php以模块的形式处理请求 LoadModule php5_module modules/libphp5.so # <Ifxxxx > 容器下文与详细说明 <IfModule unixd_module> # 运行httod服务的用户 User www # 运行httod服务的用户组 Group www </IfModule> # 管理员邮件地址 ServerAdmin you@example.com # 出错时是否显示服务器信息 ServerSignature On # On显示 # Off不显示,默认Off # Email,On的升级版，显示且点击ServerName就会向ServerAdmin中设置的邮箱发邮件 #显示的内容如下 # Apache/2.4.38 (Unix) PHP/5.6.38 Server at 192.168.73.129 Port 80 # 控制Response Header中的Server显示 ServerTokens Full # 选项有 Major | Minor | Min[imal] | Prod[uctOnly] | OS | Full # 默认是Full 这里的选项也会影响ServerSignature的显示内容，主要是详细的服务器版本号内容 # 主站点名称，域名或者IP皆可 ServerName 127.0.0.1:80 # 保持长连接设置 KeepAlive On # 一个连接服务最多请求次数 MaxKeepAliveRequests 100 # 长连接持续时间,超过该时间没有请求数据则断开连接 KeepAliveTimeOut 15 # 记录父进程PID的文件,默认值如下 PidFile "logs/httpd.pid" # 常用的资源限制配置,可减轻DOS攻击 # 设置客户端发送的HTTP请求的最大字节数 默认0 不限制 LimitRequestBody 0 # 限制为500K # LimitRequestBody 512000 # 设置客户端向服务器请求中HTTP请求头域的数量 LimitRequestFields 100 # 默认值一般为100 # 设置客户端发送的HTTP请求头的最大字节数 一般不要改动 LimitRequestFieldsize 8190 # 设置客户端发送的HTTP请求行的最大字节数 # GET / HTTP/1.1 LimitRequestLine 8190 # Dirctory容器对根目录的限制 <Directory /> # indexs 没有默认文件的情况下展示目录结构 options更多选项下文详细叙述 options indexes # 禁用.htaccess文件 AllowOverride none Require all denied </Directory> # 主站访问的根目录 DocumentRoot "/server/www/htdocs" # 对根目录的限制 <Directory "/server/www/htdocs"> # indexes允许显示文件目录 FollowSymLinks 允许文件系统使用符号连接 Options FollowSymLinks indexes # 允许使用.htacess文件 AllowOverride All Require all granted </Directory> <IfModule dir_module> # 设置默认访问文件，顺序为从左到右 DirectoryIndex index.php index.html </IfModule> # 拒绝用户访问.ht开头的文件(.htaccess) <Files ".ht*"> Require all denied </Files> # 匹配.php后缀文件，使用php处理器处理该文件 <FilesMatch "\.php$"> SetHandler application/x-httpd-php </FilesMatch> # 错误日志配置 未指定的目录都是相对于ServerRoot ErrorLog "logs/error_log" # 日志级别 LogLevel warn <IfDefine tes1> Redirect / http://www.baidu.com/ </IfDefine> # 日志格式 <IfModule log_config_module> LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common <IfModule logio_module> LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio </IfModule> # 访问日志 CustomLog "logs/access_log" common </IfModule> <IfModule alias_module> ScriptAlias /cgi-bin/ "/server/www/cgi-bin/" </IfModule> <IfModule cgid_module> </IfModule> <Directory "/server/www/cgi-bin"> AllowOverride None Options None Require all granted </Directory> <IfModule headers_module> RequestHeader unset Proxy early </IfModule> <IfModule mime_module> # 设置mime.types文件的位置，此文件规定了apache识别的文件后缀 TypesConfig conf/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz </IfModule> <IfModule proxy_html_module> Include conf/extra/proxy-html.conf </IfModule> <IfModule ssl_module> SSLRandomSeed startup builtin SSLRandomSeed connect builtin </IfModule> 容器详解分两种基本类型1. 启动时生效的容器<IfDefine> # 此容器只在启动时添加了-D参数才会生效 # 配置 <IfDefine test> # 这里的test和-D参数指定的一致 否则不起作用 Redirect / http://www.baidu.com/ </IfDefine> # 使用如下命令启动服务 /server/httpd/bin/apachectl -k start -D test # 访问根域名的请求就会被转发到百度 <IfModule> # 该容器代表xxx模块被装载了 才会起作用 # 不装载对应模块 配置文件也不会报错 <IfModule proxy_html_module> Include conf/extra/proxy-html.conf </IfModule> <IfVersion> # 判断服务器版本的容器 <IfVersion >= 2.1> # 仅在版本高于 2.1.0 的时候才生效 </IfVersion>2.常规容器(配置段)，一般都是针对各种请求常规容器的配置语法基本相同，主要有以下几项：Options选项 规定当前配置段可使用的特性语法:Options: None|All|[[+|-]Indexes][FllowSymLinks][Includes][SymLinksifOwnerMatch][ExecCGI][MultiViews] 参数:None: 不启用任何额外特性;All: 除 MultiViews 之外的所有特性。这也是Options指令的 默认设置;Indexes:如果输入的网址对应服务器上的一个文件目录，而此目录中又没有 DirectoryIndex指令(例如： DirectoryIndex index.html index.php)，那么服务器会返回目录列表;FllowSymLinks:服务器允许在此目录中使用符号连接(简单来说就是ln -s 创建的链接文件是否可用)。如果该配置选项位于 <Location>配置段中，将会被忽略;MultiViews:允许使用多重视图(基本用不到);SymLinksIfOwnerMatch:服务器仅在符号连接与目标文件或目录的所有者具有相同的用户ID时才使用它。简而言之，只有当符号连接和符号连接指向的目标文件或目录的所有者是同一用户时，才会使用符号连接。该选项需要开启FllowSymLinks前置；如果该配置选项位于 <Location>配置段中，将会被忽略;ExecCGI:允许使用 mod_cgi模块执行CGI脚本;Includes:允许使用 mod_include模块提供的服务器端包含功能。IncludesNOEXEC:允许服务器端包含，但禁用"#exec cmd"和"#exec cgi"。但仍可以从ScriptAlias目录使用"#include virtual"虚拟CGI脚本。备注参数中+-的含义Apache允许在一个目录配置中设置多个Options指令,Options选项存在继承关系。一般来说，如果一个目录被多次设置了Options，则指定特性数量最多的一个Options指令会被完全接受(其它的被忽略)，而各个Options指令之间并不会合并。但是如果我们在可选配置项前加上了符号"+"或"-"，那么表示该可选项将会被合并。所有前面加有"+"号的可选项将强制覆盖当前的可选项设置，而所有前面有"-"号的可选项将强制从当前可选项设置中去除。混合使用前面带"+"/"-"和前面不带"+"/"-"的同一可选项，可能会导致出现意料之外的结果。#示例1 <Directory /web/file> Options Indexes FollowSymLinks </Directory> <Directory /web/file/image> Options Includes </Directory> #目录/web/file/image只会被设置Includes特性 #示例2 <Directory /web/file> Options Indexes FollowSymLinks </Directory> <Directory /web/file/image> Options +Includes -Indexes </Directory> #目录/web/file/image将会被设置Includes、FollowSymLinks两种特性AllowOverride选项 规定.htaccess文件是否可用,可用哪些配置项语法:AllowOverride: None|All|AuthConfig|FileInfo|Indexes|Limit|Options参数:None: 禁止使用.htaccess(由AccessFileName决定名字)文件All: 可以使用.htaccess，且支持所有选项AuthConfig:允许使用与认证授权相关的指令(AuthDBMGroupFile, AuthDBMUserFile, AuthGroupFile, AuthName, AuthType, AuthUserFile, Require, 等)。FileInfo:允许使用控制文档类型的指令(DefaultType, ErrorDocument, ForceType, LanguagePriority, SetHandler, SetInputFilter, SetOutputFilter, mod_mime中的 Add 和 Remove 指令等等)、控制文档元数据的指令(Header, RequestHeader, SetEnvIf, SetEnvIfNoCase, BrowserMatch, CookieExpires, CookieDomain, CookieStyle, CookieTracking, CookieName)、mod_rewrite中的指令(RewriteEngine, RewriteOptions, RewriteBase, RewriteCond, RewriteRule)和mod_actions中的Action指令。Indexes:允许使用控制目录索引的指令(AddDescription, AddIcon, AddIconByEncoding, AddIconByType, DefaultIcon, DirectoryIndex, FancyIndexing, HeaderName, IndexIgnore, IndexOptions, ReadmeName, 等)。Limit:允许使用控制主机访问的指令(Allow, Deny, Order)。Options[=Option,...]:允许使用控制指定目录功能的指令(Options和XBitHack)。可以在等号后面附加一个逗号分隔的(无空格的)Options选项列表，用来控制允许Options指令使用哪些选项。Allow选项 规定允许访问的来源语法:Allow from All|ip地址|域名|其它 示例:Allow form all # 全部允许访问 Allow from a.com Allow from .net c.top # 域名方式的限制 Allow from 10.1 Allow from 192.168.1.1 192.168.1.2 # 支持部分IP地址、完整IP地址 # 其它特征控制 SetEnvIf User-Agent ^Mozilla/5\.0 let_me_in <Directory "/docroot"> Order Deny,Allow Deny from all Allow from env=let_me_in </Directory> # 只允许代理头为 Mozilla/5.0 的用户访问Deny选项 规定拒绝访问的来源语法:Deny from All|ip地址|域名|其它 # 完全同Allow一致 Order选项 控制默认访问状态语法:Order Allow,Deny # 或者 Order Deny,Allow参数：Allow,Deny:先匹配Allow的规则，再匹配Deny的规则，都匹配不上的请求默认拒绝。Deny,Allow:先匹配Deny的规则，再匹配Allow的规则，都匹配不上的请求默认允许。 2.4版本的授权方式 2.4版本的访问控制方式与2.2不同，兼容2.2的授权语句Order、Allow、Deny(不推荐使用此方式授权,未来的版本会不再提供支持)# 2.2版本 拒绝全部访问 Order Allow,Deny Deny from All # 2.4版本 Require all denied # 2.2版本 允许全部 Order Allow,Deny Allow from All # 2.4版本 Require all granted # 2.4版本常用 Require all granted #允许所有来源访问 Require all denied #拒绝所有来源访问 Require expr expression #允许表达式为true时访问 Require ip 10 172.20 192.168.2 #允许 特定IP段访问，多个段之前用空格隔开。每个段使用开头几项表示 #只允许来自域名splaybow.com的主机访问 Require host splaybow.com # 来自10.1.1.2的访问将被拒绝 Require not ip 10.1.1.2 # 只允许GET方法访问 Require method GET # 只允许代理为 Mozilla/5.0 的用户连接 SetEnvIf User-Agent ^Mozilla/5\.0 let_me_in <Directory "/server/www/htdocs/v1"> Require env let_me_in </Directory> # 授权容器(2.4新增)组合多条授权语句 # RequireAll 在此元素中包含的规则，拒绝优先执行 <RequireAll> Require all granted # 允许所有 Require not ip 192.168.1.1 # 拒绝指定ip下的访问 </RequireAll> # RequireAny 在此元素中包含的规则，允许优先执行 # 除Require All denied外，不能写其他否定规则(简单来说就是不能写not条件) <RequireAny> Require all denied Require ip 192.168.1.1 </RequireAny> # 不会用 会了在补上 <RequireNone> ... <RequireNone> 常规容器主要有文件系统、网络空间、其他，容器支持嵌套# 文件系统主要有一下几种<Directory>,<DirectoryMatch>,<Files>,<FilesMatch> <Directory '/a/b'> # 针对目录/a/b的设置 # 支持使用 Unix shell 风格匹配的通配符字符串 # ?匹配单个字符; * 匹配任意字符序列 # <Directory ~ '/^.*?/'> 可使用 ~ 设置正则(不建议，建议正则使用DirectoryMatch) <Directory> <DirectoryMatch "/.*img.*/"> # 针对正则匹配的设置 # 所有路径名中带img的 </DirectoryMatch> <Files ".htaccess"> # 匹配指定文件 # 支持使用 Unix shell 风格匹配的通配符字符串 # ~ 支持正则(不建议) </Files> <FilesMatch "/.*.txt/"> # 正则匹配 # 匹配所有的txt文件 </FilesMatch> #网络空间 # 匹配常规url <Location "/images"> </Location> # 正则匹配url <LocationMatch regex> </LocationMatch> # 代理部分在下面做基础说明 <Proxy> <ProxyMatch> # 虚拟主机容器 <VirtualHost> # 基本虚拟主机配置 <VirtualHost *:80> # xxx:8080 DocumentRoot "/www/vhost1" # 主目录 ServerName www.test.com # IP地址或域名 ServerAlias www.test1.cn #可省略 别名，也可通过别名访问 ServerAdmin stefan321@qq.com #可省略 网站管理员 ErrorLog logs/dev-error.log #可省略 错误日志 CustomLog logs/dev-access.log common #可省略 访问日志 ErrorDocument 404 logs/404.html #可省略 404错误页面 <Directory "/www/vhost1"> Options Indexes FollowSymLinks AllowOverride All Order Allow,Deny Allow from all RewriteEngine on # rewirte重写规则 也可以使用.htaccess RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] </Directory> </VirtualHost> 代理基本设置Apache官方文档使用代理功能需要加载代理模块基础代理模块 proxy_module代理模块与协议的对应关系ProtocolModuleAJP13 (Apache JServe Protocol version 1.3)mod_proxy_ajpCONNECT (for SSL)mod_proxy_connectFastCGImod_proxy_fcgiftpmod_proxy_ftpHTTP/0.9, HTTP/1.0, and HTTP/1.1mod_proxy_httpSCGImod_proxy_scgiWS and WSS (Web-sockets)mod_proxy_wstunnel一些简单的代理示例 注意 结尾的/一定要同步 # 将到/foo的请求转发到 后面的http 服务 ProxyPass "/foo" "http://foo.example.com/bar" ProxyPassReverse "/foo" "http://foo.example.com/bar" # 设置其它参数 ProxyPass "/test" "http://127.0.0.1" connectiontimeout=5 timeout=30 # 通过代理块设置限制 <Proxy "/test"> Require ip 192.168.0 </Proxy> # 不代理目标子目录 <Location "/mirror/foo/"> ProxyPass "http://backend.example.com/" </Location> <Location "/mirror/foo/i"> ProxyPass "!" </Location> # 等同如下 不可混用 ProxyPass "/mirror/foo/i" "!" ProxyPass "/mirror/foo" "http://backend.example.com" # 反向代理 负载均衡示例 <VirtualHost 192.168.73.129:80> # 虚拟机做负载均衡入口 DocumentRoot "/server/www/htdocs" # 静态资源目录 ServerName 192.168.73.129 Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED <Proxy "balancer://mycluster"> BalancerMember "http://127.0.0.1:8080" route=1 BalancerMember "http://127.0.0.2:8080" route=2 # BalancerMember "http://127.0.0.3:8080" ProxySet stickysession=ROUTEID </Proxy> ProxyPass "/index/" "balancer://mycluster/" ProxyPassReverse "/index/" "balancer://mycluster/" <Location /bm> # 设置负载均衡查看器 SetHandler balancer-manager Require all granted ProxyPass ! </Location> </VirtualHost> 设置apache支持php文件解析apahce解析php文件有三种方式module、fastcgi、phpfpm,这里只说明模块化的方式将php编译为apache的一个模块# 加载模块 LoadModule php5_module modules/libphp5.so # 设置方式1 <FilesMatch "\.php$"> SetHandler application/x-httpd-php </FilesMatch> # 设置方式2 # 在<IfModule mime_module>中添加如下内容 AddType application/x-httpd-php .phpCGI、FastCgi、php-fpm请参考这篇文章点我Apache文件解析可以看这篇文章 点我一些常用的特殊指令# Location LocationMatch ForceType image/gif # 强制设置HTTP Content-Type # 别名设置 Alias /download/ /root/download/ <Directory "/root/download"> ... </Directory> # 预留的带cgi执行权限的别名 ScriptAlias /cgi-bin/ /root/cgi/ # 将制定扩展的文件和处理程序绑定 AddHandler xxx .php # 与下面放的效果相同 <FilesMatch '/*.php$'> SetHandler xxx </FilesMatch> # 允许跨域访问 # 在VirtualHost或Directory中设置 Header set Access-Control-Allow-Origin "http://a.com" # 或者 "*"
授权操作详解授权五要素要授予的权限【权限列表中的内容】被授予访问权限的数据库或表【授权级别表中的内容】用户名地址【地址列表中的内容，mysql.user表中的host字段】密码【非必须】授权立即生效flush privileges; # 使用flush privileges;立即使权限生效，否则需要重启服务授权取消授权 语句grant 权限 on 授权范围 to username@'地址' [identified by '密码']; # 授权给账户root所有权限，允许任意地址连接，密码为123456 grant all on *.* to root@'%' identified by '123456'; # all privileges 中的 privileges 可省略 flush privileges; # 回收权限 revoke 权限 on 授权范围 from username@'地址'; # 回收root用户的查询权限 revoke select on *.* from root@'%'; flush privileges; 常用操作注意: 用户名@host 才是唯一用户查看账号root@'%'的权限 show grants for root@'%';删除用户root@'%' drop user 'root'@'%';用户改名、修改hostrename user root@'%' to admin@'localhost';修改用户root@'localhost'密码set password for root@'localhost' = password('123456');导出数据表内容select * into outfile '/tmp/outfile.txt' from loadtest; # 上面的语句只能将文件导出到mysql服务所在的主机上 mysql -h192.168.1.1 -uroot -p123456 -P3306 -e"select * from testdb.testtable;" > /tmp/loadtest.txt # 此方式可将数据导出到客户机上 授权指定列 grant select(id, username, password) on testdb.users to root@'localhost';授权存储过程 grant execute on procedure testdb.pr_add to root@'localhost'; 安全性相关删除任何无关的管理员用户和空密码的管理员用户,有需求再开删除test库(5.7没了),因为这个库默认是所有人都有权限读写,存在漏洞 drop database test;删除存放数据库的表信息。 delete from mysql.db;SSL加密设置,用途就是把数据加密,防止被截取后破解,5.6要加ssl指定文件位置配置,5.7自动开,然后执行命令就可以了.#执行命令,在数据目录创建key文件,下面这个命令是封装了整个创建过程,就不用做那么多复杂的事了 #不过这个命令文件是5.7新加入的,5.6中没有这个命令文件,但是可以放到在5.6上面用,还算方便. /usr/local/mysql/bin/mysql_ssl_rsa_setup --datadir=/data/mysql/data/ #然后看看开启了没有 mysql>SHOW VARIABLES LIKE 'have_ssl'; | have_ssl | YES | #进入mysql,授权ssl专用用户 mysql> grant all privileges on *.* to 'sslroot'@'%' identified by '123123' require ssl; #用ssl专用用户登录 mysql -usslroot -p'123123' -h127.0.0.1 #查看当前状态,SSL已启用 mysql> \s Current user: sslroot@127.0.0.1 SSL: Cipher in use is ECDHE-RSA-AES128-GCM-SHA256不过开启SSL需要谨慎,因为数据进行了加密处理,毫无疑问服务器需要消耗资源来校验密文,官方说明可能会下降25%的性能,还是比较高的.对于高并发的环境自然是性能下降明显,除非安全要求非常高,不然不建议开,一般来说只要授权限制访问IP是内网的就已经可以解决安全问题.权限相关参考内容权限列表权限关键字级别说明ALL PRIVILEGES所有授予所有权限CREATE数据库、表或索引创建数据库、表或索引权限DROP数据库或表删除数据库或表权限GRANT OPTION数据库、表或保存的程序赋予权限选项REFERENCES数据库或表ALTER表更改表，添加字段、索引、修改字段等DELETE表删除数据权限INDEX表索引权限INSERT表插入权限SELECT表查询权限CREATE VIEW视图创建视图权限SHOW VIEW视图查看视图权限ALTER ROUTINE存储过程更改存储过程权限CREATE ROUTINE存储过程创建存储过程权限EXECUTE存储过程执行存储过程权限FILE服务器主机上的文件访问文件访问权限CREATE TEMPORARY TABLES服务器管理创建临时表权限LOCK TABLES服务器管理锁表权限CREATE USER服务器管理创建用户权限PROCESS服务器管理查看进程权限RELOAD服务器管理执行flush-hosts,flush-logs,flush-privileges,flush-status,flush-tables,flush-threads,refresh,reload等命令的权限REPLICATION CLIENT服务器管理复制权限REPLICATION SLAVE服务器管理复制权限SHOW DATABASES服务器管理查看数据库权限SHUTDOWN服务器管理关闭数据库权限SUPER服务器管理执行kil线程权限授权级别grant和revoke可以在几个层次上控制访问权限授权范围说明整个服务器使用 *.*整个数据库使用on database.*特定表使用on database.table特定的列特定的存储过程地址列表关键字说明%匹配所有主机localhostlocalhost不会被解析成IP地址，直接通过UNIXsocket连接127.0.0.1会通过TCP/IP协议连接，并且只能在本机访问::1::1就是兼容支持ipv6的，表示同ipv4的127.0.0.1x.x.x.x指定的地址x.x.x.%指定的地址段
通用启动脚本参数设置EXECON程序启动的路径PID进程号记录文件路径service_name服务名称设置完成后保存在/etc/init.d目录下授权chmod +x 文件名service 文件名 (start stop restart status)注意事项：# chkconfig: 58 74 这条是不能删除的，不然会报错："service php-fpmd does not support chkconfig"chkconfig 文件名 --add 设置开机启动就设置不了了。# chkconfig: 58 74 （58是启动优先级，74是停止优先级，优先级范围是0－100，数字越大，优先级越低） # chkconfig 文件名 --add //设置开机启动 # chkconfig --list //查看service里设置列表脚本内容如下#!/bin/bash #-1------------配置 # 主程序脚本存放路径及脚本名称（这里的把主程序功能代码EXCON写进这个启动脚本了） EXECON="/usr/local/nginx/sbin/nginx" # 进程PID记录文件位置及名称 PID="/var/run/nginx.pid" [ ! -f $PID ] && : > $PID # 服务名称（提示信息服务名称,可以中英文） service_name="nginx" ############### # SysV Init Information # chkconfig: - 58 74 ### BEGIN INIT INFO # Required-Start: $network $local_fs $remote_fs # Required-Stop: $network $local_fs $remote_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 #-3--------------启动和关闭 server_id=`cat $PID` case "$1" in start) -n $server_id && echo "(server_id=$server_id) $service_name is runing..." && exit $EXECON & pid=$! echo $((pid+1)) > $PID echo "serverd to start successfully!" ;; stop) ! -n $server_id && echo -e "$service_name is not startd... \nYou can start it with start or restart..." && exit kill $server_id &> /dev/null : > $PID echo "serverd shut down successfully!" ;; status) if -n $server_id ;then echo "(server_id=$server_id) $service_name is runing..." else echo -e "$service_name is not startd... \nYou can start it with start or restart..." fi ;; restart) $0 stop $0 start ;; *) echo "Please use start, stop, restart or status as first argument" ;; esac
Linux下搭建蚂蚁笔记-- 蚂蚁私有云笔记官网蚂蚁笔记官网 蚂蚁笔记MongoDB数据库搭建蚂蚁笔记的后台使用的是MongoDB数据库MongoDB安装最详细指南戳这里个人自建日记的话，使用单机服务就可以满足需求，按说明启动MongoDB服务获取蚂蚁笔记下载地址： http://leanote.org/#downloadlinux获取 cd /www/wwwroot wget https://sourceforge.net/projects/leanote-bin/files/2.6.1/leanote-linux-386-v2.6.1.bin.tar.gz安装蚂蚁笔记tar -zxvf leanote-linux-386-v2.6.1.bin.tar.gz cd leanote vim conf/app.conf # 修改默认配置文件 app.secret=xxx # 这个一定要改 随便改 越复杂越好 i18n.default_language=en-us #默认是英文的，修改为中文 i18n.default_language=zh-cn //db的参数根据上一步启动的数据来填写，默认不需要更改 db.host=127.0.0.1 db.port=27017 db.dbname=leanote # required修改完配置文件保存即可导入初始数据mongorestore -h 127.0.0.1 -d leanote --dir /www/wwwroot/leanote/mongodb_backup/leanote_install_data启动服务mkdir -p /www/wwwroot/leanote.log nohup /bin/bash /www/wwwroot/leanote/bin/run.sh >> /www/wwwroot/leanote/log/run.log 2>&1 & //以守护进程的方式运行访问 服务器ip:9000即可
MongoDB数据库服务集群部署安装文档MongoDB服务安装1.1 获取MongoDB安装包当前登录用户角色为root 所在目录为/root 操作系统为 Centos6.1下载地址：https://www.mongodb.com/download-center/community根据服务器系统获取安装包，当前安装的机器为centos6.1版本，选择REHL 6.2版本wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.6.12.tgz1.2 安装MongoDB1.2.1 准备工作创建安装目录、数据存放目录、日志目录mkdir /opt/mongodb # 程序安装目录 mkdir -p /var/mongodb/data # 数据存放目录 mkdir -p /var/mongodb/log # mongodb日志目录 1.2.2 安装MongoDB# 解压缩文件 tar -zxvf mongodb-linux-x86_64-rhel62-3.6.12.tgz # 移动文件到/opt/mongodb mv mongodb-linux-x86_64-rhel62-3.6.12/* /opt/mongodb/ # 删除 空目录 rm mongodb-linux-x86_64-rhel62-3.6.12 -r 1.2.3 单实例MongoDB配置文件mongdodb的服务启动依赖配置文件的设置或者纯命令行参数来设置，命令行参数的方式测试还好，生成环境上不利于管理，这里创建配置文件用来设置mongodb，默认是不存在配置文件的。vim /opt/mongodb/mongodb.conf # 以下为配置文件详细配置 # 数据库文件位置 dbpath=/var/mongodb/data # 日志文件路径 logpath=/var/mongodb/log/mongodb.log # pid文件路径 pidfilepath=/opt/mongodb/mongod.pid # 追加的方式写日志 logappend=true # 绑定ip 默认绑定127.0.0.1 bind_ip=127.0.0.1 # 绑定端口 默认27017 port=27017 # 以守护进程的方式运行 fork=true # 不同数据库存放在不同目录 directoryperdb=true # 注意该参数需要服务器使用XFS filesystem # 上述参数如果服务器使用的非XFS filesystem，启动会出错，将该参数改为false wq 保存配置文件详细的配置参数可参考：https://www.cnblogs.com/cwp-bg/p/9479945.htmlhttps://www.03sec.com/3176.shtmlYAML格式配置文件创建MongoDB在2.6版本开始支持使用yaml格式的配置文件，官方建议使用yaml格式文档上述相同参数的yaml格式配置文件如下vim /opt/mongodb/mongodb.yaml # ------------以下为yaml格式配置文件内容---------------- systemLog: destination: "file" #日志使用文件 path: "/var/mongodb/log/mongod.log" #日志文件路径 logAppend: true #允许日志追加记录 processManagement: fork: true #后台守护进程启动 pidFilePath: "/opt/mongodb/mongod.pid" #pid文件路径 net: bindIp: "127.0.0.1" #绑定ip地址 port: 27017 #实例监听端口 storage: dbPath: "/var/mongodb/data" #数据文件路径 directoryPerDB: false #一个库一个文件,此参数与服务器使用的文件系统有关 注意：以下操作涉及到的配置文件如无特殊说明，均为yaml格式配置1.2.4 启动服务# -f 指定配置文件路径 等同 --config # 以下两个命令二选一 效果完全一致 /opt/mongodb/bin/mongod -f /opt/mongodb/mongodb.conf /opt/mongodb/bin/mongod -f /opt/mongodb/mongodb.yaml 启动成功后会提示如下child process started successfully, parent exiting使用ps查看是否成功启动 ps aux|grep 'mongod' 1.2.5 指定用户mongodb运行mongodb服务# 创建用户组mongodb groupadd mongodb # 创建用户 mongodb (不允许登录) useradd mongodb -g mongodb -s /bin/false # 修改文件所有者 chown -R mongodb:mongodb /opt/mongodb # 安装目录 chown -R mongodb:mongodb /var/mongodb # 数据存储目录 # 使用ps查看是否有mongodb进程 ps aux|grep 'mongod' 如果有进程，使用kill结束进程kill -9 [pid]使用mongodb用户启动mongodb服务sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mongodb.yaml 1.2.6 添加环境变量vim /etc/profile 文件最后增加如下配置export PATH=$PATH:/opt/mongodb/bin 加载配置，使环境变量生效source /etc/profile 配置成功后，可直接使用命令 mongod -f /opt/mongodb/mongodb.yaml 来开启mongodb服务1.2.7 编写自启动脚本源码安装的mongodb没有启动脚本，需要写一个启动脚本vim /opt/mongodb/mongodb.sh #----------------以下为脚本内容------------------------- #!/bin/bash #desc mongodb boot shell MGDB_PATH="/opt/mongodb" MGDB_CONF="${MGDB_PATH}/mongodb.yaml" MGDB_USER="mongodb" MGDB_GROUP="mongodb" cd ${MGDB_PATH} MGDB_START(){ if [ ` ps -ef|grep 'mongod -f'|grep -v grep|wc -l` > 0 ];then echo "MongoDB already start" exit 1 fi sudo -u ${MGDB_USER} -g ${MGDB_GROUP} ${MGDB_PATH}/bin/mongod -f ${MGDB_CONF} if [ $? -eq 0 ];then echo -n "MongoDB start " echo -n "[" echo -ne "\033[32m" echo -n "Successful" echo -ne "\e[0m" echo "]" else echo "MongoDB start failed" fi } MGDB_STOP(){ sudo -u ${MGDB_USER} -g ${MGDB_GROUP} ${MGDB_PATH}/bin/mongod -f ${MGDB_CONF} --shutdown if [ $? -eq 0 ];then echo -n "MongoDB stop " echo -n "[" echo -ne "\033[32m" echo -n "Successful" echo -ne "\e[0m" echo "]" else echo "MongoDB stop failed" fi } MGDB_STATUS(){ ps -ef|grep 'mongod -f'|grep -v grep if [ $? != 0 ];then echo "MongoDB is STOP" fi } case "$1" in start) MGDB_START ;; stop) MGDB_STOP ;; status) MGDB_STATUS ;; restart) MGDB_STOP MGDB_START ;; *) echo $"Usage: $0 { start | stop | status | restart }" exit 1 esac 保存脚本后添加到自启动程序# 添加可执行权限 chmod +x /opt/mongodb/mongodb.sh # 添加自启动服务 cp /opt/mongodb/mongodb.sh /etc/init.d/mongodb Centos6.x使用service管理服务 # 启动服务 service mongodb start # 停止服务 service mongodb stop # 查看服务状态 service mongodb status Centos7.x使用service管理服务 # 启动服务 systemctl start mongodb # 停止服务 systemctl stop mongodb # 查看服务状态 systemctl status mongodb 1.2.8 对外提供服务# 修改/opt/mongodb/mongodb.yaml vim /opt/mongodb/mongodb.yaml # 将bindIp修改为0.0.0.0 bindIp=0.0.0.0 # 保存 # 重启 mongodb服务 service mongodb restart Centos6.x查看防火墙状态service iptables status如果防火墙开启状态，则关闭防火墙service iptables stopCentos7.xsystemctl stop firewalld.service1.2.9 使用shell操作mongodb直接执行如下命令 可连接到本地mongodb服务mongo 使用参数可指定服务器mongo --host x.x.x.x --post 27017集群部署配置2.1 准备工作现有机器M5-M9,ip地址如下机器名ip地址说明M510.1.1.245 M610.1.1.246 M710.1.1.247 M810.1.1.248 M910.1.1.249 所有机器按如上步骤，部署成单机版本mongodb快捷方式注意本快捷方式仅适用于此次的环境，非通用。可略过此部分内容。因为MongoDB的安装方式仅仅是解压缩，相当于windows上的绿色程序，不存在编译过程，服务器系统一致的情况下，可将安装好的mongdb打包，发送到需要部署的机器上。cd /opt && zip mongodb.zip mongodb -r # 使用scp远程复制到需要部署的服务器 scp mongodb.zip root@x.x.x.x:/opt # 依次执行以下命令可完成安装部署 unzip /opt/mongodb.zip -d /opt mkdir -p /var/mongodb/data mkdir -p /var/mongodb/log useradd mongodb chown -R mongodb:mongodb /var/mongodb chown -R mongodb:mongodb /opt/mongodb cp /opt/mongodb/mongodb.sh /etc/init.d/mongodb echo 'export PATH=$PATH:/opt/mongodb/bin' >> /etc/profile source /etc/profile service mongodb start 2.2 说明MongoDB共有三种集群搭建方式，分别为Replica Set（副本集）、Sharding（分片）Master-Slaver（主从）【目前已不推荐使用！！！】三种集群方式的详细说明在下面的部署方案中，实现的方式都是通过更改配置来实现的，所以不同的部署方式有不同的配置文件，集群部署的配置文件命名规则统一为如下格式mon_xx_yy_0.yamlmon : 固定格式 代表mongodbxx : 代表集群方式 枚举[‘ms’,’rs’,’s’] 分别代表三种部署方式首字母小写yy : 代表所在集群方式中的节点类型ms集群中 包含[‘master’,’slaver’]两种 rs集群中 包含[‘primary’,’ secondaries’,’ arbiter’]三种 s集群中 包含[‘shard,’config’, ’route’]两种0 : 启动权重， 集群部署的机器有启动顺序的要求。0为首先需要启动的机器，其他机器权重一次后延，同权重机器启动顺序无要求。备注：启动失败就随时查看日志文件，失败的原因会在日志中展示。2.3 Master-Slaver主从复制 集群搭建2.3.1 Master-Slaver部署说明最简单的集群搭建，不过准确说也不能算是集群，只能说是主备。并且官方已经不推荐这种方式，所以在这里只是简单配置，搭建方式也相对简单。节点说明：master：主从复制中的主节点，只允许有一个，对外提供读写服务slaver: 从节点，不提供服务，只同步主节点的数据，主节点故障，可手动切换。官方文档地址：https://docs.mongodb.com/v3.6/core/master-slave/index.html优点：搭建简单、可用于备份、故障恢复、读扩展等。缺点：不支持故障转移，对大量数据的支持较差备注：可在程序层面实现故障转移，可用于备份,故障恢复,读扩展等。2.3.2 服务器规划所有机器都已部署成单实例mongodb服务器，原配置文件为所在位置为/opt/mongodb/mongodb.yaml,不同部署方式有不同的配置文件。机器名ip地址配置文件说明M510.1.1.245mon_ms_slaver_1.yaml备节点M610.1.1.246mon_ms_master_0.yaml主节点M710.1.1.247mon_ms_slaver_1.yaml备节点M810.1.1.248mon_ms_slaver_1.yaml备节点M910.1.1.249mon_ms_slaver_1.yaml备节点2.3.3配置文件编写在M6服务器上编辑master配置文件vim /opt/mongodb/mon_ms_master_0.yaml # ---------------以下为master服务器配置-------------------- systemLog: destination: "file" #日志使用文件 path: "/var/mongodb/log/mongod.log" #日志文件路径 logAppend: true #允许日志追加记录 processManagement: fork: true #后台守护进程启动 pidFilePath: "/opt/mongodb/mongod.pid" #pid文件路径 net: bindIp: "10.1.1.246" #服务器自己的IP地址 port: 27017 #实例监听端口 storage: dbPath: "/var/mongodb/data" #数据文件路径 directoryPerDB: false #一个库一个文件此参数与系统文件有关 在M5服务器上编辑slaver 配置文件vim mon_ms_slaver_1.yaml # ----------------以下为slaver服务器详细配置-------------------------------- systemLog: destination: "file" #日志使用文件 path: "/var/mongodb/log/mongod.log" #日志文件路径 logAppend: true #允许日志追加记录 processManagement: fork: true #后台守护进程启动 pidFilePath: "/opt/mongodb/mongod.pid" #pid文件路径 net: bindIp: "10.1.1.245" # 服务器的ip port: 27017 #实例监听端口 storage: dbPath: "/var/mongodb/data" #数据文件路径 directoryPerDB: false #一个库一个文件此参数与系统文件有关 将slaver配置文件复制到M7、M8、M9机器上，或者在其他机器上手动创建配置文件，注意更改IP地址。2.3.4 服务启动登入M6机器，启动master节点注意：这里不能使用启动脚本来启动文件，启动脚本中的配置文件固定为单实例配置，如需使用启动脚本，需要更改启动脚本中的MGDB_CONF变量# 启动脚本的修改, 可略过 vim /etc/init.d/mongodb # 原 MGDB_CONF="${MGDB_PATH}/mongodb.yaml" # 修改后 MGDB_CONF="${MGDB_PATH}/mon_ms_master_0.yaml" # 其他slaver服务器类似，修改配置文件所在即可 注意：有的时候服务无法启动，只是提示使用without --fork 启动，可通过日志查看原因，或者在确保数据已备份的前提下，将/var/mongodb/data/ 下的内容清空即可命令如下rm /var/mongodb/data/* -rf 启动master# --master参数 代表当前服务使用master模式运行 sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mon_ms_master_0.yaml --master 依次登录M5、M7、M8、M9机器使用以下命令启动slaver节点# --slave指定运行模式 --source 指定master的ip:port sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mon_ms_slaver_1.yaml --slave --source 10.1.1.246:27017 服务成功启动后，查看master日志，有客户端连入的字样received client metadata2.3.5 数据同步测试在任意机器上使用mongo连接master， 在主从模式中，只有master节点可读写，slaver节点只能读。mongo --host 10.1.1.246 # ---以下命令执行环境为mongo的shell客户端 use school; # 选择school库，没有会创建 db.createCollection('student'); # 创建名为student的集合 # 向集合中插入三条数据 db.student.insert({'name':'Xinu1', score:99}); db.student.insert({'name':'Xinu2', score:100}); db.student.insert({'name':'Xinu3', score:80}); exit # 更换任意slaveer节点，查看数据是否同步 mongo --host 10.1.1.249 # ---以下命令执行环境为mongo的shell客户端 rs.slaveOk(); # 正常slaver节点不允许读取操作，使用此方法，获取当前连接临时读取授权 show dbs； # 查看当前节点中的数据库 use school; show collections; # 查看当前节点中的集合 db.student.find(); # 查看集合student中的数据 主从模式搭建费成功的话，可以看到如下图的数据。主从复制搭建成功。2.3.6 故障处理master-slaver复制模式所有的服务都有master提供，master故障后，需要手动调整任意一个slaver节点为master节点以M5节点为例，将M5节点变为master节点# 查找当前mongod服务进程号 ps aux|grep 'mongod'|grep -v grep # 杀掉该进程 kill -9 [pid] # 删除 M5节点中数据目录中的 local.* rm /var/mongodb/data/local.* -rf # 重命名配置文件 mv /opt/mongodb/mon_ms_slaver_1.yaml /opt/mongodb/mon_ms_master_0.yaml # 以--master方式运行 sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/ mon_ms_master_0.yaml --master 其他从节点停止服务，重新启动 参数--source修改为10.1.1.245:270172.4 Replica Set副本集 集群搭建2.4.1 Replica Set部署说明官方推荐的搭建方式，同时也是最流行的集群搭建方式。支持故障自动转移，读写分离，有较好的性能和容灾能力。一个副本集即为服务于同一数据集的多个 MongoDB 实例,其中一个为主节点,其余的都为从节点。主节 点上能够完成读写操作,从节点仅能用于读操作。主节点需要记录所有改变数据库状态的操作,这些记录 保存在 oplog 中,这个文件存储在 local 数据库,各个从节点通过此 oplog 来复制数据并应用于本地,保持 本地的数据与主节点的一致。oplog 具有幂等性,即无论执行几次其结果一致,这个比 mysql 的二进制日 志更好用。集群中的各节点还会通过传递心跳信息来检测各自的健康状况。当主节点故障时,多个从节点会触发一次 新的选举操作,并选举其中的一个成为新的主节点(通常谁的优先级更高,谁就是新的主节点),心跳信 息默认每 2 秒传递一次。节点说明：primary：主节点，只有一个，对外提供读写服务，记录在其上所有操作的 oplog。secondary: 从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。默认情况下,从节点不支持外部读取,但可以设置;副本集的机制在于主节点出现故障的时候,余下的节点会选举出一个新的主节点,从而保证系统可以正常运行。arbiter：仲裁节点，副本集部署非必须部署仲裁节点，仲裁节点是为了更好的选举主节点。不复制数据,仅参与投票。由于它没有访问的压力,比较空闲,因此不容易出故障。由于副本集出现故障的时候,存活的节点必须大于副本集节点总数的一半, 否则无法选举主节点,或者主节点会自动降级为从节点,整个副本集变为只读。因此,增加一个不容易出故障的仲裁节点,可以增加有效选票,降低整个副本集不可用的风险。仲裁节点可多于一个。也就是说只参与投票，不接收复制的数据，也不能成为活跃节点。如果副本集的节点总数为奇数，则无需部署仲裁节点，节点总数为偶数，则配置一个仲裁节点拥有选举权。为测试使用仲裁节点，本次部署5个节点，1主3从1仲裁。官方文档地址：https://docs.mongodb.com/v3.6/tutorial/deploy-replica-set其它参考文档：https://www.cnblogs.com/kevingrace/p/5685486.html优点：自动故障转移、自动恢复、读写分离缺点：部署略有难度提升 备注：比较流行的部署方式，满足大部分业务场景需求2.4.2 服务器规划所有机器都已部署成单实例mongodb服务器，原配置文件为所在位置为/opt/mongodb/mongodb.yaml,不同部署方式有不同的配置文件。注意：如果机器部署过其它方式的集群，在部署前，请清空所有实例的data目录rm /var/mongodb/data/* -rf 机器名ip地址配置文件说明M510.1.1.245mon_rs_arbiter_2.yaml仲裁节点M610.1.1.246mon_rs_primary_0.yaml主节点M710.1.1.247mon_rs_secondary_1.yaml从节点M810.1.1.248mon_rs_secondary_1.yaml从节点M910.1.1.249mon_rs_secondary_1.yaml从节点2.4.3 配置文件编写Replica Set副本建官方推荐数据开启auth校验，下面是开启auth校验的准备工作准备工作(以下操作均在M6节点上)使用单例模式的配置，开启服务，使用mongo客户端连接，并创建一个用户# 单实例模式开启mongodb服务 sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mongodb.yaml # 使用mongo连接实例 mongo --host 10.1.1.246 # mongodb的auth校验非常完善，本文档不做详细赘述，内容实在太多了 # 参考地址 https://docs.mongodb.com/v3.6/core/authentication/ # 创建root角色组下的用户 用户名为 rsadmin 密码123456 use admin; db.createUser({user:'rsadmin', pwd:'123456', roles:['root']}); # 该root角色组拥有管理用户组、集群、数据的绝大部分权限，实际生产环境中应谨慎创建 exit auth校验是针对数据库层面的校验，可以对应为mysql的用户概念，主要是为了数据安全而集群间的认证也是有必要的，这里开启keyFile。使用openssl命令创建key# -base64 使用base64编码 512代表字节长度 openssl rand -base64 512 >> /opt/mongodb/mongo.key chmod 600 /opt/mongodb/mongo.key # 修改key文件权限 # 将创建的mongo.key复制到其他节点的相同路径下，方便管理 scp /opt/mongodb/mongo.key root@10.1.1.247:/opt/mongodb/ # 其他机器ip依次替换即可 # 复制成功后需要改动mongo.key文件的所有者 chown mongodb:mongodb /opt/mongodb/mongo.key准备工作做完，配置M6 Primary节点配置vim /opt/mongodb/mon_rs_primary_0.yaml # -------------以下为配置文件的内容-------------------- systemLog: destination: "file" #日志使用文件 path: "/var/mongodb/log/mongod.log" #日志文件路径 logAppend: true #允许日志追加记录 component: replication: rollback: verbosity: 5 processManagement: fork: true #后台守护进程启动 pidFilePath: "/opt/mongodb/mongod.pid" #pid文件路径 net: bindIp: "10.1.1.246" port: 27017 #实例监听端口 storage: dbPath: "/var/mongodb/data" #数据文件路径 directoryPerDB: false #一个库一个文件此参数与系统文件有关 journal: enabled: true replication: replSetName: 'rs0' # 副本集的名字，所有节点都要一致 security: keyFile: '/opt/mongodb/mongo.key' # key文件路径 上一步生成的 clusterAuthMode: 'keyFile' # 校验方式为keyFile 配置M7、M8、M9 Secondary节点配置(与Primary节点无区别，除了IP)vim /opt/mongodb/mon_rs_secondary_1.yaml # -------------以下为配置文件的内容-------------------- systemLog: destination: "file" #日志使用文件 path: "/var/mongodb/log/mongod.log" #日志文件路径 logAppend: true #允许日志追加记录 component: replication: rollback: verbosity: 5 processManagement: fork: true #后台守护进程启动 pidFilePath: "/opt/mongodb/mongod.pid" #pid文件路径 net: bindIp: "10.1.1.247" port: 27017 #实例监听端口 storage: dbPath: "/var/mongodb/data" #数据文件路径 directoryPerDB: false #一个库一个文件此参数与系统文件有关 journal: enabled: true replication: replSetName: 'rs0' # 副本集的名字，所有节点都要一致 security: keyFile: '/opt/mongodb/mongo.key' # key文件路径 上一步生成的 clusterAuthMode: 'keyFile' # 校验方式为keyFile 三台从节点机器配置除IP外完全一致。Arbiter 仲裁节点 M5节点配置文件仲裁节点与其他节点配置不同，需要创建一个专用的数据存放目录，该目录不存放其他节点数据，只是存储仲裁节点用到的数据。 # 创建仲裁节点存放数据目录 mkdir /var/mongodb/abr # 修改所有者 chown -R mongodb:mongodb /var/mongodb # 编辑 仲裁节点的配置内容 vim /opt/mongodb/mon_rs_secondary_1.yaml # -------------以下为配置文件的内容-------------------- systemLog: destination: "file" #日志使用文件 path: "/var/mongodb/log/mongod.log" #日志文件路径 logAppend: true #允许日志追加记录 processManagement: fork: true #后台守护进程启动 pidFilePath: "/opt/mongodb/mongod.pid" #pid文件路径 net: bindIp: "10.1.1.245" port: 27017 #实例监听端口 storage: dbPath: "/var/mongodb/abr" #数据文件路径 directoryPerDB: false #一个库一个文件此参数与系统文件有关 replication: replSetName: 'rs0' security: keyFile: '/opt/mongodb/mongo.key' 2.4.4 服务启动MongoDB服务停止的三种方式主节点以单实例启动后，需要关闭，关闭的方式用三种，第一种是查询pid kill结束进程，上文有介绍。这种强制停止的方式可能会导致下次启动不起来，需要删除data目录下的mongod.lock文件。第二种，使用mongodb自带的停止服务的方式，在启动服务的命令最后加上 --shutdown 参数就能正常关闭服务。启动命令为sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mongodb.yaml 则停止命令为sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mongodb.yaml --shutdown第三种，使用mongo客户端连接后，停止服务mongo --host 10.1.1.246 use admin; db.shutdownServer(); 推荐使用第二种方式启动主节点Primary M6节点sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mon_rs_primary_0.yaml 依次启动M7、M8、M9 节点sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mon_rs_secondary_1.yaml 启动仲裁节点M5sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mon_rs_arbiter_2.yaml 都启动成功后，现有的5个节点其实谁都可以成为Primary节点，还需要在主节点上配置任意节点使用mongo连接主节点服务mongo --host 10.1.1.246 # 因为开启了auth校验，现在各种命令执行都会提示未校验，需要登录下 use admin; db.auth('rsadmin', '123456'); # 校验成功会提示1,可以执行各种命令了 # 副本集设置初始化 rs.initiate() # 添加三个从节点 rs.add('10.1.1.247:27017'); rs.add('10.1.1.248:27017'); rs.add('10.1.1.249:27017'); # 添加仲裁节点 rs.addArb('10.1.1.245:27017'); # 如果添加失败 反馈的errMsg都会有提示失败的原因 # 添加成功后查看状态 rs.status(); # 以下为创建成功的状态显示 { "set" : "rs0", "date" : ISODate("2019-05-09T03:08:44.242Z"), "myState" : 1, "term" : NumberLong(1), "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1557371321, 1), "t" : NumberLong(1) }, "readConcernMajorityOpTime" : { "ts" : Timestamp(1557371321, 1), "t" : NumberLong(1) }, "appliedOpTime" : { "ts" : Timestamp(1557371321, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1557371321, 1), "t" : NumberLong(1) } }, "members" : [ { "_id" : 0, "name" : "10.1.1.246:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 1791, "optime" : { "ts" : Timestamp(1557371321, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2019-05-09T03:08:41Z"), "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "electionTime" : Timestamp(1557370530, 1), "electionDate" : ISODate("2019-05-09T02:55:30Z"), "configVersion" : 5, "self" : true, "lastHeartbeatMessage" : "" }, { "_id" : 1, "name" : "10.1.1.247:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 752, "optime" : { "ts" : Timestamp(1557371321, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1557371321, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2019-05-09T03:08:41Z"), "optimeDurableDate" : ISODate("2019-05-09T03:08:41Z"), "lastHeartbeat" : ISODate("2019-05-09T03:08:43.694Z"), "lastHeartbeatRecv" : ISODate("2019-05-09T03:08:42.804Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncingTo" : "10.1.1.246:27017", "syncSourceHost" : "10.1.1.246:27017", "syncSourceId" : 0, "infoMessage" : "", "configVersion" : 5 }, { "_id" : 2, "name" : "10.1.1.248:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 270, "optime" : { "ts" : Timestamp(1557371321, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1557371321, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2019-05-09T03:08:41Z"), "optimeDurableDate" : ISODate("2019-05-09T03:08:41Z"), "lastHeartbeat" : ISODate("2019-05-09T03:08:43.909Z"), "lastHeartbeatRecv" : ISODate("2019-05-09T03:08:42.373Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncingTo" : "10.1.1.249:27017", "syncSourceHost" : "10.1.1.249:27017", "syncSourceId" : 3, "infoMessage" : "", "configVersion" : 5 }, { "_id" : 3, "name" : "10.1.1.249:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 513, "optime" : { "ts" : Timestamp(1557371321, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1557371321, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2019-05-09T03:08:41Z"), "optimeDurableDate" : ISODate("2019-05-09T03:08:41Z"), "lastHeartbeat" : ISODate("2019-05-09T03:08:43.697Z"), "lastHeartbeatRecv" : ISODate("2019-05-09T03:08:42.809Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncingTo" : "10.1.1.246:27017", "syncSourceHost" : "10.1.1.246:27017", "syncSourceId" : 0, "infoMessage" : "", "configVersion" : 5 }, { "_id" : 4, "name" : "10.1.1.245:27017", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 492, "lastHeartbeat" : ISODate("2019-05-09T03:08:43.683Z"), "lastHeartbeatRecv" : ISODate("2019-05-09T03:08:42.303Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "configVersion" : 5 } ], "ok" : 1, "operationTime" : Timestamp(1557371321, 1), "$clusterTime" : { "clusterTime" : Timestamp(1557371321, 1), "signature" : { "hash" : BinData(0,"iEDe4wcimYrLW/cIa0ODX3dHFJY="), "keyId" : NumberLong("6688855494104186883") } } } # 查看当前副本集的配置 rs.conf(); # 以下为副本集配置内容 { "_id" : "rs0", "version" : 5, "protocolVersion" : NumberLong(1), "members" : [ { "_id" : 0, "host" : "10.1.1.246:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "10.1.1.247:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "10.1.1.248:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 3, "host" : "10.1.1.249:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 4, "host" : "10.1.1.245:27017", "arbiterOnly" : true, "buildIndexes" : true, "hidden" : false, "priority" : 0, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "catchUpTimeoutMillis" : -1, "catchUpTakeoverDelayMillis" : 30000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("5cd396a0b36b6340a8634b62") } } 重点关注三个参数hidden： 该参数对Secondary节点起作用，是否显示该节点，如果该节点为true,则该节点只参与数据的备份，有选举权，不能成为主节点，不参与读数据。可以作为数据的备份节点。priority：改参数代表当前节点的权重，越大权重越高，权重的左右在于决定选举权的顺序，权重越大，则在选举中，优先变成Primary节点，可以看到仲裁节点中该参数为0，没有成为主节点的权利。其他节点该参数为1。votes：决定该节点是否有选举权，可以理解为当前节点是否有选举Primary节点的资格。2.4.5 数据同步测试写服务只有Primaryj节点提供，连接主节点已连接的略过此步骤mongo --host 10.1.1.246 use admin; db.auth('rsadmin', '123456'); # 创建school 库 use school; db.createCollection('student'); db.student.insert({name:'张三'}); db.student.insert({name:'李四'}); 使用其他节点连接其他任意Secondary节点进行测试，这里也需要认证，认证同Primary节点完全一致mongo --host 10.1.1.247 use admin; db.auth("rsadmin", "123456"); # 从节点默认不提供读写服务，获取临时授权 rs.slaveOk(); # 该授权仅仅能获取读的授权，写必须在主节点上 use school; db.student.find(); # 以下为内容 { "_id" : ObjectId("5cd3a12895f1c931dac32f9c"), "name" : "张三" } { "_id" : ObjectId("5cd3a12d95f1c931dac32f9d"), "name" : "李四" } 数据同步成功2.4.6 故障自动恢复1．停止主节点M6 模拟主节点故障宕机sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mon_rs_primary_0.yaml --shutdown连接其他任意节点：mongo --host 10.1.1.247 # 认证 use admin; db.auth('rsadmin','123456'); # 查看状态 rs.status(); # -------状态------------- { "set" : "rs0", "date" : ISODate("2019-05-09T03:58:58.347Z"), "myState" : 2, "term" : NumberLong(2), "syncingTo" : "10.1.1.249:27017", "syncSourceHost" : "10.1.1.249:27017", "syncSourceId" : 3, "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1557374332, 1), "t" : NumberLong(2) }, "readConcernMajorityOpTime" : { "ts" : Timestamp(1557374332, 1), "t" : NumberLong(2) }, "appliedOpTime" : { "ts" : Timestamp(1557374332, 1), "t" : NumberLong(2) }, "durableOpTime" : { "ts" : Timestamp(1557374332, 1), "t" : NumberLong(2) } }, "members" : [ { "_id" : 0, "name" : "10.1.1.246:27017", "health" : 0, "state" : 8, "stateStr" : "(not reachable/healthy)", "uptime" : 0, "optime" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDurable" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2019-05-09T03:58:56.955Z"), "lastHeartbeatRecv" : ISODate("2019-05-09T03:44:19.236Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "Connection refused", "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "configVersion" : -1 }, { "_id" : 1, "name" : "10.1.1.247:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 4577, "optime" : { "ts" : Timestamp(1557374332, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2019-05-09T03:58:52Z"), "syncingTo" : "10.1.1.249:27017", "syncSourceHost" : "10.1.1.249:27017", "syncSourceId" : 3, "infoMessage" : "", "configVersion" : 5, "self" : true, "lastHeartbeatMessage" : "" }, { "_id" : 2, "name" : "10.1.1.248:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 3283, "optime" : { "ts" : Timestamp(1557374332, 1), "t" : NumberLong(2) }, "optimeDurable" : { "ts" : Timestamp(1557374332, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2019-05-09T03:58:52Z"), "optimeDurableDate" : ISODate("2019-05-09T03:58:52Z"), "lastHeartbeat" : ISODate("2019-05-09T03:58:58.064Z"), "lastHeartbeatRecv" : ISODate("2019-05-09T03:58:58.063Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncingTo" : "10.1.1.249:27017", "syncSourceHost" : "10.1.1.249:27017", "syncSourceId" : 3, "infoMessage" : "", "configVersion" : 5 }, { "_id" : 3, "name" : "10.1.1.249:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 3527, "optime" : { "ts" : Timestamp(1557374332, 1), "t" : NumberLong(2) }, "optimeDurable" : { "ts" : Timestamp(1557374332, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2019-05-09T03:58:52Z"), "optimeDurableDate" : ISODate("2019-05-09T03:58:52Z"), "lastHeartbeat" : ISODate("2019-05-09T03:58:58.035Z"), "lastHeartbeatRecv" : ISODate("2019-05-09T03:58:57.056Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "electionTime" : Timestamp(1557373472, 1), "electionDate" : ISODate("2019-05-09T03:44:32Z"), "configVersion" : 5 }, { "_id" : 4, "name" : "10.1.1.245:27017", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 3506, "lastHeartbeat" : ISODate("2019-05-09T03:58:58.037Z"), "lastHeartbeatRecv" : ISODate("2019-05-09T03:58:56.485Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "configVersion" : 5 } ], "ok" : 1, "operationTime" : Timestamp(1557374332, 1), "$clusterTime" : { "clusterTime" : Timestamp(1557374332, 1), "signature" : { "hash" : BinData(0,"WCV4july6HgCfPIOsSktsZKp3zI="), "keyId" : NumberLong("6688855494104186883") } } } 可以看到 10.1.1.246节点的状态时不可到达，不健康的，而10.1.1.249则变成了Primary节点。Secondary节点被选举为Primary节点的优先权通过参数priority来控制，越大优先级越高，通过该参数可指定从节点变为主节点的顺序，写程序的时候就可以通过配置多个ip地址来实现容灾，自动恢复。节点自动恢复，重新启动M6节点sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mon_rs_primary_0.yaml 在任意节点上登录mongo执行rs.status(); 可以看到M6机器自动变为了Secondary节点。2.5 Sharding 分片集群搭建2.5.1 Sharding 分片集群部署说明 Sharding 分片集群部署说明分片是一种可以水平扩展的模式,在数据量很大时特给力,实际大规模应用一般会采用这种架构去构建。sharding分片很好的解决了单台服务器磁盘空间、内存、cpu等硬件资源的限制问题，把数据水平拆分出去，降低单节点的访问压力。每个分片都是一个独立的数据库，所有的分片组合起来构成一个逻辑上的完整的数据库。因此，分片机制降低了每个分片的数据操作量及需要存储的数据量，达到多台服务器来应对不断增加的负载和数据的效果。节点说明：分片服务器（Shard Server）Mongodb3.6版本及之后 该节点必须是副本集 mongod 实例,用于存储实际的数据块,实际生产环境中一个 shard server 角色可由几台机器组成一个 relica set 承担,防止主机单点故障。这是一个独立普通的mongod进程,保存数据信息。可以是一个副本集也可以是单独的一台服务器。配置服务器（Config Server）Mongodb3.4版本及之后 该节点必须是副本集 mongod 实例,存储了整个 Cluster Metadata,其中包括 chunk 信息。 这是一个独立的mongod进程,保存集群和分片的元数据,即各分片包含了哪些数据的信息。最先开始建立,启用日志功能。像启动普通的 mongod 一样启动 配置服务器,指定configsvr 选项。不需要太多的空间和资源,配置服务器的 1KB 空间相当于真实数据的 200MB。保存的只是数据的分布表。路由服务器（Route Server） mongos实例,前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用 起到一个路由的功能,供程序连接。本身不保存数据,在启动时从配置服务器加载集群信息,开启 mongos 进程需要知道配置服务器的地址,指定configdb选项。官方文档地址：https://docs.mongodb.com/v3.6/tutorial/deploy-sharded-cluster-hashed-sharding/其它参考文档：https://blog.51cto.com/bigboss/2160311优点：超大数据量支持，可横向扩展，容灾性能极强，数据分片存储有效提升磁盘读写瓶颈缺点：部署难度较大、成本较高。满足的生产环境的部署方式至少需要8台服务器 。备注：大规模应用一般会采用这种架构去构建2.5.2 服务器规划所有机器都已部署成单实例mongodb服务器，原配置文件为所在位置为/opt/mongodb/mongodb.yaml,不同部署方式有不同的配置文件。注意：如果机器部署过其它方式的集群，在部署前，请清空所有实例的data目录，如果使用新的data路径则不需要清除rm /var/mongodb/data/* -rf 由于shard和config节点必须是副本集，而机器数量不够，这里通过配置不同端口来实现多台服务器的模拟。这里的配置文件命名格式不再遵循上述的命名格式。机器名ip地址-端口配置文件说明M5-2701710.1.1.245:27017shard1-rs-1.yamlshard1M5-2701810.1.1.245:27018shard1-rs-2.yamlshard1M5-2701910.1.1.245:27019shard1-rs-3.yamlshard1M6-2701710.1.1.246:27017shard2-rs-1.yamlshard2M6-2701810.1.1.246:27018shard2-rs-2.yamlshard2M6-2701910.1.1.246:27019shard2-rs-3.yamlshard2M710.1.1.247config-rs-1.yamlconfigM810.1.1.248config-rs-2.yamlconfigM910.1.1.249mongos.yamlmongos服务器规划说明：M5节点搭建为3节点（1主2从0仲裁）的rs0副本集 作为shard1节点M6节点搭建为3节点（1主2从0仲裁）的rs1副本集 作为 shard2节点M7,M8搭建成2节点（1主1从0仲裁）的config副本集 作为config节点M9 作为mongos节点 起到路由的作用。真正的生产环境中，所用节点都为独立服务器，且mongos应部署多个，每个应用程序服务器都应该部署一个mongos2.5.3 准备工作创建通用校验key# 创建通用公钥文件 openssl rand -base64 512 > /opt/mongodb/mon.key # 修改文件所有者 chown -R mongodb:mongodb /opt/mongodb/mon.key # 修改文件权限 chmod -R 600 /opt/mongodb/mon.key # 依次复制到其他节点 #注意：复制过去以后，该文件的所有者为root 需要重新改成mongodb scp /opt/mongodb/mon.key 10.1.1.246:/opt/mongodb/ scp /opt/mongodb/mon.key 10.1.1.247:/opt/mongodb/ scp /opt/mongodb/mon.key 10.1.1.248:/opt/mongodb/ scp /opt/mongodb/mon.key 10.1.1.249:/opt/mongodb/ 2.5.4 config副本集部署官方推荐config的副本集生产环境上不低于3个节点，这里只搭建了一个2节点的config serverM7节点# M7 节点 # 创建数据存放目录、日志存放目录、修改所有者 mkdir -p /var/mongodb/configdata chown -R mongodb:mongodb /var/mongodb # 配置 config-rs-1.yaml 文件 vim /opt/mongodb/config-rs-1.yaml # 内容如下 systemLog: destination: "file" #日志使用文件 path: "/var/mongodb/log/config.log" #日志文件路径 logAppend: true #允许日志追加记录 processManagement: fork: true #后台守护进程启动 pidFilePath: "/opt/mongodb/config.pid" #pid文件路径 net: bindIp: "0.0.0.0" port: 27017 #实例监听端口 storage: dbPath: "/var/mongodb/configdata" #数据文件路径 directoryPerDB: false #一个库一个文件此参数与系统文件有关 replication: replSetName: 'config' security: keyFile: '/opt/mongodb/mon.key' sharding: clusterRole: 'configsvr' M8节点# M8 节点 # 创建数据存放目录、日志存放目录、修改所有者 mkdir -p /var/mongodb/configdata chown -R mongodb:mongodb /var/mongodb # 配置 config-rs-2.yaml 文件 vim /opt/mongodb/config-rs-2.yaml # 内容如下 systemLog: destination: "file" #日志使用文件 path: "/var/mongodb/log/config.log" #日志文件路径 logAppend: true #允许日志追加记录 processManagement: fork: true #后台守护进程启动 pidFilePath: "/opt/mongodb/config.pid" #pid文件路径 net: bindIp: "0.0.0.0" port: 27017 #实例监听端口 storage: dbPath: "/var/mongodb/configdata" #数据文件路径 directoryPerDB: false #一个库一个文件此参数与系统文件有关 replication: replSetName: 'config' security: keyFile: '/opt/mongodb/mon.key' sharding: clusterRole: 'configsvr' 启动M7、M8上的服务# 分别在M7、M8节点启动服务 sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/config-rs-1.yaml sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/config-rs-2.yaml 配置config副本集# 连接M7 或者M8 mongo # 初始化config副本集 rs.initiate({ _id: "config", configsvr: true, version: 1, protocolVersion: 1, writeConcernMajorityJournalDefault: true, members: [ { _id: 0, host: "10.1.1.247:27017", arbiterOnly: false, buildIndexes: true, hidden: false, priority: 66, tags: {}, slaveDelay: 0, votes: 1 }, { _id: 1, host: "10.1.1.248:27017", arbiterOnly: false, buildIndexes: true, hidden: false, priority: 55, tags: {}, slaveDelay: 0, votes: 1 } ], settings: { chainingAllowed : true, } }); # 会提示ok:1的字样 通过rs.status() 查看实际运行情况 2.5.5 shard1副本集部署# shard1 副本集配置 # 创建数据存放目录、日志存放目录、修改所有者 mkdir -p /var/mongodb/data27017 mkdir -p /var/mongodb/data27018 mkdir -p /var/mongodb/data27019 chown -R mongodb:mongodb /var/mongodb # 配置 shard1-rs-1.yaml 文件 vim /opt/mongodb/shard1-rs-1.yaml # 内容如下 systemLog: destination: "file" #日志使用文件 path: "/var/mongodb/log/shard1-rs1.log" #日志文件路径 logAppend: true #允许日志追加记录 processManagement: fork: true #后台守护进程启动 pidFilePath: "/opt/mongodb/shard1-rs1.pid" #pid文件路径 net: bindIp: "0.0.0.0" port: 27017 #实例监听端口 storage: dbPath: "/var/mongodb/data27017" #数据文件路径 directoryPerDB: false #一个库一个文件此参数与系统文件有关 replication: replSetName: 'shard1' security: keyFile: '/opt/mongodb/mon.key' sharding: clusterRole: 'shardsvr' # 配置 shard1-rs-2.yaml 文件 vim /opt/mongodb/shard1-rs-2.yaml # 内容如下 systemLog: destination: "file" #日志使用文件 path: "/var/mongodb/log/shard1-rs2.log" #日志文件路径 logAppend: true #允许日志追加记录 processManagement: fork: true #后台守护进程启动 pidFilePath: "/opt/mongodb/shard1-rs2.pid" #pid文件路径 net: bindIp: "0.0.0.0" port: 27018 #实例监听端口 storage: dbPath: "/var/mongodb/data27018" #数据文件路径 directoryPerDB: false #一个库一个文件此参数与系统文件有关 replication: replSetName: 'shard1' security: keyFile: '/opt/mongodb/mon.key' sharding: clusterRole: 'shardsvr' # 配置 shard1-rs-3.yaml 文件 vim /opt/mongodb/shard1-rs-3.yaml # 内容如下 systemLog: destination: "file" #日志使用文件 path: "/var/mongodb/log/shard1-rs3.log" #日志文件路径 logAppend: true #允许日志追加记录 processManagement: fork: true #后台守护进程启动 pidFilePath: "/opt/mongodb/shard1-rs3.pid" #pid文件路径 net: bindIp: "0.0.0.0" port: 27019 #实例监听端口 storage: dbPath: "/var/mongodb/data27019" #数据文件路径 directoryPerDB: false #一个库一个文件此参数与系统文件有关 replication: replSetName: 'shard1' security: keyFile: '/opt/mongodb/mon.key' sharding: clusterRole: 'shardsvr' # 启动三个服务 sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/shard1-rs-1.yaml sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/shard1-rs-2.yaml sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/shard1-rs-3.yaml # 连接27017 mongo # 初始化shard1副本集 rs.initiate({ _id: "shard1", version: 1, protocolVersion: 1, writeConcernMajorityJournalDefault: true, members: [ { _id: 0, host: "10.1.1.245:27017", arbiterOnly: false, buildIndexes: true, hidden: false, priority: 66, tags: { }, slaveDelay: 0, votes: 1 }, { _id: 1, host: "10.1.1.245:27018", arbiterOnly: false, buildIndexes: true, hidden: false, priority: 55, tags: { }, slaveDelay: 0, votes: 1 }, { _id: 2, host: "10.1.1.245:27019", arbiterOnly: false, buildIndexes: true, hidden: false, priority: 33, tags: { }, slaveDelay: 0, votes: 1 } ], settings: { chainingAllowed : true, } }); # 提示 { "ok" : 1 } 则设置成功，通过rs.status() 查看实际运行情况 备注：当前运行的副本集是没有读写执行权限的，分片搭建成功后最后在创建一个用户来操作绑定0.0.0.0以后，通过127.0.0.1的地址登入的用户操作权限略大于通过10.1.1.245的用户，可以执行副本集初始化操作副本集的设置有两种方式，一种是2.4章节中所使用的通过rs.add方法的方式添加从节点，哪个节点发起添加从节点的动作，哪个节点就自动变为主节点，该方式要求用户要有较高的权限，而未添加用户之前，通过127.0.0.1登入的用户也没有add的权限，为了减少操作，这里采用初始化时即配置节点的方式。该配置方式通过priority参数的大小指定端口27017的服务为Primary节点。2.5.6 shard2副本集部署将2.5.4中的所有内容中的shard1关键字替换为shard2 地址修改为10.1.1.246即可与M5节点的搭建方式完全一致，过程略过，如果搭建不出来，You may not be able to make a living by programming.2.5.7 mongos节点部署创建mongos数据存放目录 更改目录所有者mkdir -p /var/mongodb/route chown -R mongodb:mongodb /var/mongodb 创建mongos节点的配置文件# ----------以下为配置文件内容------------------ systemLog: destination: "file" #日志使用文件 path: "/var/mongodb/log/route.log" #日志文件路径 logAppend: true #允许日志追加记录 processManagement: fork: true #后台守护进程启动 pidFilePath: "/opt/mongodb/mongos.pid" #pid文件路径 net: bindIp: "0.0.0.0" port: 27017 #实例监听端口 sharding: configDB: "config/10.1.1.247:27017,10.1.1.248:27017" security: keyFile: '/opt/mongodb/mon.key' 2.5.8 服务启动shard1、shard2、config三个副本集已启动，这里就是把三个副本集联系到一起。开启mongos服务 注意：这里是作为路由节点 启动的命令是mongos不是mongodsudo -u mongodb -g mongodb /opt/mongodb/bin/mongos -f /opt/mongodb/mongos.yaml # 登录shell mongo # 创建高权限用户 root 123456 use admin; db.createUser({user: "root",pwd: "123456",roles: ['__system']}); exit # 创建成功后退出 # 重新连接 mongo use admin; db.auth("root", '123456'); # 添加分片服务器 sh.addShard("shard1/10.1.1.245:27017,10.1.1.245:27018,10.1.1.245:27019"); sh.addShard("shard2/10.1.1.246:27017,10.1.1.246:27018,10.1.1.246:27019"); # 会提示 "shardAdded" : "shard2","ok" : 1类似字样 成功 sh.status(); # 查看当前集群状态 # 为了测试分片效果，修改分片大小 # 修改分片大小为1M 默认为64M use config; db.settings.save({_id:"chunksize",value:1}); use school; db.createCollection('student'); # 对库和student集合使用分片，片键为age 方式为 1 sh.enableSharding('school'); sh.shardCollection("school.student",{'age':1}); # 插入2w条数据 for (i = 1; i <= 20000; i++) db.student.insert({age:(i%100), name:"学生"+i, address:i+"辽宁", country:"中国", course:"cousre"+"(i%12)"}); # 查看分片结果 sh.status(); 如上图所示，根据片键age升序分片成功片键选择：官网文档：https://docs.mongodb.com/v3.6/core/sharding-shard-key/https://docs.mongodb.com/v3.6/sharding/#sharding-strategy其他文档: http://mongoing.com/understand-mongodb-shardkeyhttp://www.mongoing.com/blog/post/on-selecting-a-shard-key-for-mongodb片键的分片方式有四种：1：升序，-1降序，hashed：哈希分布， 还有一种远程分片策略,这里不做详细赘述。原创，转载请注明来源。
sh脚本异常：/bin/sh^M:bad interpreter: No such file or directory
sh脚本异常：/bin/sh^M:bad interpreter: No such file or directory在windows系统中编辑的.sh文件可能有不可见字符，所以在Linux系统下执行会报以上异常信息。vim 目标脚本文件:set ff可以看到 fileformat=doc:set ff=unix可修改成功 wq保存