最近薅了百度云双12的羊毛，1核2G一年150。突然想起以前大学整个宿舍通宵开黑挖泥土的岁月，所以刚好趁着这台服务器，打算自己搭建一个我的世界服务器，重温一下以前的感觉。系统要求 -google到的MC系统要求:CPU：双核内存：20-40人2GB，30-60人3GB，60+人8GB上面就是服务器端的需求，如果只是和小伙伴们一起玩，也并不需要多优秀的服务器。下面是我的配置：CPU：单核内存：2GLinux系统：CentOS 7.3 x86_64安装JavaMC是用Java写的（当然现在也有别的语言写的版本），由于服务器端的MC是一个jar包，我们在配置之后通过运行jar包来开启服务器端，同时我们在客户端上打开后通过IP地址即可搜索并进入服务器。所以我们首先要先安装Java。通过下面的方法来安装：yum install -y java-1.8.0-openjdk下载MC服务器端这里有一个要求，就是你和你的小伙伴要拥有同样版本的MC。不同的版本对应着不同的服务器端，所以我们要下载正确的版本。如何看MC版本呢，一般进入游戏后，游戏左下角会有版本显示。知道了版本号，那么用命令就可以下载对应版本的服务器端了。需要根据版本号补全命令格式：wget https://s3.amazonaws.com/Minecraft.Download/versions/<你要下载的版本号>/minecraft_server.<你要下载的版本号>.jar 例子：博主这边选择安装了比较稳定的1.12版本wget https://s3.amazonaws.com/Minecraft.Download/versions/1.12/minecraft_server.1.12.jar等下载提示结束后，minecraft_server.1.12.jar就躺在当前目录了。MC服务器，启动！我们就可以使用命令来运行MC服务器：java -Xms[初始启动分配内存] -Xmx[最大分配内存] -jar [jar包所在路径]/minecraft_server.[版本号].jar nogui例子：java -Xms256m -Xmx512m -jar /home/mc/minecraft_server.1.12.jar nogui关于命令最后一个参数 nogui，是分开的单词 no gui，意思是不需要图形界面，这样会大大减小内存的使用，如果你的Linux是有图形界面的，就可以不打这个 nogui。启动成功上面的命令输入完成后，等待参数由0%一直到100%就启动完成啦！下面给出博主启动完成的后几行显示：[05:58:08] [Server thread/INFO]: Loaded 488 advancements [05:58:08] [Server thread/INFO]: Preparing start region for level 0 [05:58:09] [Server thread/INFO]: Preparing spawn area: 0% [05:58:10] [Server thread/INFO]: Preparing spawn area: 41% [05:58:11] [Server thread/INFO]: Preparing spawn area: 76% [05:58:11] [Server thread/INFO]: Done (4.263s)! For help, type "help" or "?"MC，Shell脚本启动！我们如果一直使用上面那一句启动的话是不是非常麻烦！每次都要复制粘贴，那么我们可以写一个简单的Shell脚本，放在jar包所在目录，每次启动的时候直接启动脚本就能进入游戏了。vim start-game.sh编辑内容如下：#!/bin/sh java -Xms256m -Xmx512m -jar /home/mc/minecraft_server.1.12.jar nogui保存退出，每次启动游戏只需要运行下面命令即可:bash start-game.shMC服务器，关闭！按 Ctrl + C 来停止当前服务器MC服务起最常见的启动失败我们在第一次运行完jar包后，无论是否运行成功，都能发现当前目录下多出了一堆文件，运行失败的时候其实就是配置除了一点问题。我们在当前目录找一下文件：eula.txtvim eula.txt按i键进入编辑模式，找到如下一行把 false 改为 trueeula=false保存退出按 esc输入 :wq客户端连接MC服务器失败上面都启动成功之后，就可以下载对应服务器版本的客户端。下载好后启动，点击多人游戏，添加服务器，服务器地址输入我们云服务器的公网IP，就可连接上去愉快的玩耍了。但是这时候可能会发现就是怎么连接都失败，如果遇到这个情况，我们需要检查下服务器配置文件，先在jar包目录下找到文件server.propertices 并编辑：vim server.propertices找到这一行online-mode:true将true改为false，这是正版验证服务的设置关于 server.propertices 文件，这边就不多做介绍了，可通过下面的链接了解详情服务器配置文件详细设置我的世界WiKi保持服务会话因为博主用的是云服务器，需要通过使用ssh工具来连接到服务器启动游戏服务，但是一般服务器和ssh工具都会有连接会话的超时设置，在一段时间没有在服务器上操作后，会自动断开ssh会话，这时这个会话中的任务就会被杀掉，那小伙伴们游戏玩着玩着就与服务器断开连接了。这个时候我们可以使用Linux上这个 GNU Screen 工具来解决上述问题GNU Screen是一款由GNU计划开发的用于命令行终端切换的自由软件。用户可以通过该软件同时连接多个本地或远程的命令行会话，并在其间自由切换。GNU Screen可以看作是窗口管理器的命令行界面版本。它提供了统一的管理多个会话的界面和相应的功能。安装 screenyum install -y screen语法：screen -AmRvx -ls -wipe-h <行数>-s 参数说明-A 将所有的视窗都调整为目前终端机的大小。-d <作业名称> 将指定的screen作业离线。-h <行数> 指定视窗的缓冲区行数。-m 即使目前已在作业中的screen作业，仍强制建立新的screen作业。-r <作业名称> 恢复离线的screen作业。-R 先试图恢复离线的作业。若找不到离线的作业，即建立新的screen作业。-s 指定建立新视窗时，所要执行的shell。-S <作业名称> 指定screen作业的名称。-v 显示版本信息。-x 恢复之前离线的screen作业。-ls或--list 显示目前所有的screen作业。-wipe 检查目前所有的screen作业，并删除已经无法使用的screen作业。常用screen参数screen -S yourname -> 新建一个叫yourname的sessionscreen -ls -> 列出当前所有的sessionscreen -r yourname -> 回到yourname这个sessionscreen -d yourname -> 远程detach某个sessionscreen -d -r yourname -> 结束当前session并回到yourname这个session保持我们的MC服务会话新建一个screen会话screen -S mcs当输入这个命令后，就会进入 mcs 会话，在当前会话下，输入上面的启动脚本命令，确认游戏正常启动后，就可以放着不管了，只要不是服务器挂掉了，服务就会一直运行着。
相关知识HTTP/HTTPS 是什么?简单来说，HTTP 是一个传输网页内容的协议，比如我们浏览一个网页，网页上的文字、图片、 CSS 、 JS 等文件都是通过 HTTP 协议传输到我们的浏览器，然后被我们看到。因为 HTTP 是明文传输的，通过 HTTP 协议传输的内容很容易被偷看和篡改，为了安全（你肯定不想被人偷看或者篡改网页内容吧，比如网站银行密码什么的。）就为 HTTP 协议再加上了一层 SSL/TLS 安全协议，所以就有了 HTTPS 。SSL/TLS 是什么？SSL 是指安全套接字层（Secure Sockets Layer），内心纯洁的同学也可以理解为「带安全套的 HTTP」，因为带了安全套，所以当然会比较安全。TLS 是 传输层安全协议（Transport Layer Security），SSL 和 TLS 是同一个东西的不同阶段，理解为同一个东西也行，都是安全协议就对了。为什么要部署 HTTPS？说到底，就是 HTTPS 更安全。甚至为了安全，一个专业可靠的网站， HTTPS 是必须的。 Firefox 和 Chrome 都计划将没有配置 SSL 加密的 HTTP 网站标记为不安全，目前它们也正在联合其他相关的基金会与公司推动整个互联网 HTTPS 化，现在大家访问的一些主要的网站。如 Google 多年前就已经全部启用 HTTPS ，国内的淘宝、搜狗、知乎、百度等等也全面 HTTPS 了。甚至 Google 和百度的搜索结果也正在给予 HTTPS 的网站更高的排名和优先收录权。怎么部署 HTTPS 呢？你只需要有一张被信任的 CA （ Certificate Authority ）也就是证书授权中心颁发的 SSL 安全证书，并且将它部署到你的网站服务器上。一旦部署成功后，当用户访问你的网站时，浏览器会在显示的网址前加一把小绿锁，表明这个网站是安全的，当然同时你也会看到网址前的前缀变成了 HTTPS ，不再是 HTTP 了。怎么获得 SSL 安全证书呢？理论上，我们自己也可以签发 SSL 安全证书，但是我们自己签发的安全证书不会被主流的浏览器信任，所以我们需要被信任的证书授权中心（ CA ）签发的安全证书。而一般的 SSL 安全证书签发服务都比较贵，比如 Godaddy 、 GlobalSign 等机构签发的证书一般都需要20美金一年甚至更贵，不过为了加快推广 HTTPS 的普及， EEF 电子前哨基金会、 Mozilla 基金会和美国密歇根大学成立了一个公益组织叫 ISRG （ Internet Security Research Group ），这个组织从 2015 年开始推出了 Let’s Encrypt 免费证书。这个免费证书不仅免费，而且还相当好用，所以我们就可以利用 Let’s Encrypt 提供的免费证书部署 HTTPS 了。Let’s Encrypt 简介前面已经介绍过， Let’s Encrypt 是 一个叫 ISRG （ Internet Security Research Group ，互联网安全研究小组）的组织推出的免费安全证书计划。参与这个计划的组织和公司可以说是互联网顶顶重要的先驱，除了前文提到的三个牛气哄哄的发起单位外，后来又有思科（全球网络设备制造商执牛耳者）、 Akamai 加入，甚至连 Linux 基金会也加入了合作，这些大牌组织的加入保证了这个项目的可信度和可持续性。Certbot 简介ISRG 的发起者 EFF （电子前哨基金会）为 Let’s Encrypt 项目发布了一个官方的客户端 Certbot ，利用它可以完全自动化的获取、部署和更新安全证书。虽然第三方工具也可以使用，但是官方工具更权威，风险也更小，而且遇到问题也更容易解决，毕竟有官方的支持。实际操作Certbot 使用方法Certbot 的官网是https://certbot.eff.org/, 我们打开这个链接，选择自己使用的 web server 和操作系统。选择完之后，官网就会显示出对应的安装操作步骤。以目前我所使用的服务器为例，web server 使用Nginx(1.12)，操作系统是CentOS(7.3)。因为 Certbot 打包在EPEL中，所以在安装 Certbot 之前要先安装EPELyum -y install epel-release然后按着官网给出的步骤提示命令安装 Certbotyum install python2-certbot-nginx安装完毕后，继续输入官网提示命令certbot --nginx运行此命令会自动获取证书，并且 Certbot 会自动编辑Nginx配置文件配置HTTPS服务。这边在运行配置命令时遇到一个坑ImportError: No module named 'requests.packages.urllib3'可以看出是缺少一个模块包，看配置命令在命令台的输出，Certbot 是用 python 来写 Nginx 配置。既然是用的 python，可以通过 pip list 命令查看 python 的依赖包列表。但是查看是已经存在的，这个问题很快通过 Certbot 在 github 上的一个 Issues 找到了答案（Issues链接）。目前看是包的版本依赖有问题，执行以下命令进行依赖包的重装pip uninstall requests pip uninstall urllib3 yum remove python-urllib3 yum remove python-requests yum install python-urllib3 yum install python-requests yum install certbot再次执行 certbot --nginx 命令成功。命令执行后首先会提示输入一个邮箱地址，主要作用是订阅一些通知，输入后回车。[root@izuf6fco0zwyipdq9485s2z ~]# certbot --nginx Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator nginx, Installer nginx ▽ Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): demo@mail.com // 演示邮箱 Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -回车后 Certbot 就会自动请求下载 Let's Encrypt 证书，并设置 Nginx 配置文件。期间会有一些同意相关协议和选择哪个网站配置的交互，这个看输出文字就能明白意思。... ▽ server { (A)gree/(C)ancel: a - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about our work encrypting the web, EFF news, campaigns, and ways to support digital freedom. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Y)es/(N)o: y Starting new HTTPS connection (1): supporters.eff.org Which names would you like to activate HTTPS for? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: kisstime.top - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate numbers separated by commas and/or spaces, or leave input blank to select all options shown (Enter 'c' to cancel): 1 Obtaining a new certificate Performing the following challenges: http-01 challenge for kisstime.top Cleaning up challenges ...但是这边到 Certbot 设置 Nginx 配置文件的时候遇到一个坑，报如下一个错误An unexpected error occurred: UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 2: ordinal not in range(128) Please see the logfiles in /var/log/letsencrypt for more details.熟悉 python 的同学应该对这个错误比较了解。不过博主 python 还是用的比较少，花了点时间了解了一下。在解决错误之前，首先要了解unicode和utf-8的区别。unicode指的是万国码，是一种“字码表”。而utf-8是这种字码表储存的编码方法。unicode不一定要由utf-8这种方式编成bytecode储存，也可以使用utf-16,utf-7等其他方式。目前大多都以utf-8的方式来变成bytecode。其次，Python中字符串类型分为byte string 和 unicode string两种。如果在python文件中指定编码方式为utf-8(#coding=utf-8)，那么所有带中文的字符串都会被认为是utf-8编码的byte string（例如：mystr="你好"），但是在函数中所产生的字符串则被认为是unicode string。问题就出在这边，unicode string 和 byte string 是不可以混合使用的，一旦混合使用了，就会产生这样的错误。例如：self.response.out.write("你好"+self.request.get("argu"))其中，"你好"被认为是byte string，而self.request.get("argu")的返回值被认为是unicode string。由于预设的解码器是ascii，所以就不能识别中文byte string。然后就报错了。那理解了这个错误原因后，我这边首先想到的就是网站的 Nginx 配置文件中是否含有中文。打开一看，确实存在中文注释。将注释去掉，重新执行命令成功不在报错接着命令交互会提示是否将所有HTTP重定向到HTTPS，我这边选择全部重定向也就是「2」。Cleaning up challenges Deploying Certificate to VirtualHost: //这边会显示你的网站配置文件目录 Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2 Redirecting all traffic on port 80 to ssl in //这边会显示你的网站配置文件目录 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Congratulations! You have successfully enabled https://kisstime.top You should test your configuration at: https://www.ssllabs.com/ssltest/analyze.html?d=kisstime.top - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: .../fullchain.pem Your key file has been saved at: .../privkey.pem Your cert will expire on 2019-02-14. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-leOK，当完成上面最后一步后，输入如上信息后就表明 HTTPS 配置成功了！我们可以通过提示中的 SSL Server Test 网址来测试网站是否能够 HTTPS 来进行访问You should test your configuration at: https://www.ssllabs.com/ssltest/analyze.html?d=kisstime.top事实证明，高兴的太早了。。。通过测试网站和直接访问域名发现网站都是访问不了。思考了一下，确认下服务器的443端口是否开启，我这边用的是阿里云的服务器，登录控制台查看安全组规则，发现确实是443端口没有开启，配置开启后，重新访问成功。其他Nginx的设置说明基本上 Certbot 会在对应的 Nginx 配置文件加上下面的参数：server { # ... other configs # SSL 设置 listen 443 ssl; # set crt and key ssl_certificate .../fullchain.pem; ssl_certificate_key .../privkey.pem; # include 基本的 ssl 设置 include .../options-ssl-nginx.conf; # Certbot 也会生成一把 Diffie-Hellman 密钥 ssl_dhparam .../ssl-dhparams.pem; # ... other configs }自动更新证书Let’s Encrypt 免费SSL证书用起来非常方便，但每次申请只有三个月有效期，在每次到期之前都需要重新申请，Certbot 已经提供了一键续订的命令certbot renew我们可以通过添加此条命令的cron作业（或systemd计时器）来安排证书的自动续订SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin 0 0,12 * * * certbot renew --quiet Certbot 的 log 路径Certbot 的 log 预设路径在 /var/log/letsencrypt，有需要可以去确认查看。相关第三方certbot-auto是对脚本certbot的封装，可以设置系统环境或自动升级。参考资料牛顿曾经说过：如果说我看得比别人更远些，那是因为我站在巨人的肩膀上。（If I have seen further, it is by standing on the shoulders of giants.）感谢。https://certbot.eff.org/https://linuxstory.org/deploy-lets-encrypt-ssl-certificate-with-certbothttps://blog.csdn.net/use_my_heart/article/details/51303317https://blog.hellojcc.tw/2018/05/02/setup-https-with-letsencrypt-on-nginx/博客原文链接:point_right:点击链接
服务器配置1 登录到服务器修改sshd的配置文件vim /etc/ssh/sshd_config找到以下内容，去掉前面的注释（#）RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys重启sshd服务service sshd restart本机配置1 本机生成公钥和私钥（已生成跳过）ssh-keygen -t rsa一路回车即可。默认在 ~/.ssh目录生成两个文件id_rsa ：私钥 id_rsa.pub ：公钥2 将本地公钥导入到服务器认证文件中ssh-copy-id -i ~/.ssh/id_rsa.pub root@你的公网IP3 修改 mac 下的配置文件 ~/.ssh/config （没有则创建）Host aliyun ### 别名 Hostname 192.168.10.10 ###公网 IP Port 22 ###端口 User root ###登录账号 IdentityFile ~/.ssh/id_rsa ###本机私钥地址4 使用ssh连接ssh aliyun
最近刚好因为活动买了一台新的服务器，空着也空着，刚好可以用来搭博客使用，搭建博客这件事。之前也做过很多次，不管是用静态博客生成器，还是手写一个博客项目。都尝试过，思来想去，这次打算用用WordPress，听闻许久，也该用用看了。安装Nginxyum -y install nginx安装Mysql5.7安装 mysql 官方 yum 源rpm -ivh https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm查看 MySQL yum 源yum list | grep mysql发现只有 mysql80 的包，这是因为没有开启 mysql57 的包，关闭80包，开启57包。yum-config-manager --disable mysql80-community yum-config-manager --enable mysql57-community报错-bash: yum-config-manager: 未找到命令这个是因为系统默认没有安装这个命令，这个命令在yum-utils 包里，可以通过命令yum -y install yum-utils 安装就可以了。安装 yum-utils 包yum -y install yum-utils再次查看Mysql包列表出现57安装包安装 Mysql57yum -y install mysql-community-server启动 Mysql57服务systemctl start mysqld查看初始密码grep 'temporary password' /var/log/mysqld.log登录 Mysql，修改密码mysql -uroot -p set password for root@localhost = password('你的密码');如果提示错误，那是因为 mysql57 对密码的复杂度进行了限制，依次执行下列命令，取消复杂度限制，再修改set global validate_password_policy=0; set global validate_password_mixed_case_count=0; set global validate_password_number_count=3; set global validate_password_special_char_count=0; set global validate_password_length=3;提示错误[root@izuf6fco0zwyipdq9485s2z ~]# mysql -uroot -p Enter password: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)如下操作修复# 先关闭服务 systemctl stop mysqld # 跳过权限验证 mysqld --user=root --skip-grant-tables & # 登录 mysql -u root mysql # 设置密码 UPDATE user SET authentication_string=PASSWORD('new password') where USER='root'; # 刷新设置 FLUSH PRIVILEGES;安装 PHP7.2php7.2 版本的 yum 源在 webtatic 上，但还有一部分需要依赖 epel-release 。EPEL(Extra Packages for Enterprise Linux )，是基于Fedora的一个项目，为“红帽系”的操作系统提供额外的软件包，适用于RHEL、CentOS和Scientific Linux。安装 epel-releaseyum -y install epel-release安装完成后，在 /etc/yum.repos.d 目录下，就会多一个 epel.repo 的文件，还有一个 testing 的测试文件。当系统通过 yum 进行安装软件时，如果需要 epel 里的扩展包，就会自动下载安装。安装 webtatic yum 源rpm -ivh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm安装完成后，在 /etc/yum.repos.d 目录下会多出 webtatic.repo 和 webtatic-archive.repo 两个文件，还有一个 testing 的测试文件。查看 php 可以安装的包 yum list | grep php72上面这些 rpm 包就是 webtatic 的 yum 源里面的包啦。我们要安装的就是 php72 的核心包 mod_php72w 和核心扩展包 php72w-cli 、php72w-fpm、php72w-common、php72w-devel。其它扩展选项包请根据需要安装，例如需要 php72w-gd 后期可单独安装。安装php72yum -y install mod_php72w php72w-cli php72w-fpm php72w-common php72w-devel通过这种方式安装的 php72 的 php.ini 文件与我们认识的不太一样，它类似于 nginx.conf 存在一个主配置，通过类型 include 方法，包含指定文件夹下的模块配置文件。启动php-fpmsystemctl start php-fpm安装 WordPress下载wordpresswget https://cn.wordpress.org/wordpress-4.9.4-zh_CN.tar.gz解压到/home/目录下tar -zxvf wordpress-4.9.4-zh_CN.tar.gz -C /home/登陆mysql并添加数据库，命名为wordpressmysql -uroot -p create database wordpress; show databases;备份nginx的配置文件cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak修改配置文件vim /etc/nginx/conf.d/default.conf重启Nginx服务时候报错，查看错误日志vim /var/log/nginx/error.log 2018/11/14 17:15:23 [emerg] 14151#0: bind() to 0.0.0.0:80 failed (98: Address already in use) 2018/11/14 17:15:23 [emerg] 14151#0: bind() to [::]:80 failed (98: Address already in use) 2018/11/14 17:15:23 [emerg] 14151#0: bind() to 0.0.0.0:80 failed (98: Address already in use) 2018/11/14 17:15:23 [emerg] 14151#0: bind() to [::]:80 failed (98: Address already in use) 2018/11/14 17:15:23 [emerg] 14151#0: bind() to 0.0.0.0:80 failed (98: Address already in use) 2018/11/14 17:15:23 [emerg] 14151#0: bind() to [::]:80 failed (98: Address already in use) 2018/11/14 17:15:23 [emerg] 14151#0: bind() to 0.0.0.0:80 failed (98: Address already in use) 2018/11/14 17:15:23 [emerg] 14151#0: bind() to [::]:80 failed (98: Address already in use) 2018/11/14 17:15:23 [emerg] 14151#0: bind() to 0.0.0.0:80 failed (98: Address already in use) 2018/11/14 17:15:23 [emerg] 14151#0: bind() to [::]:80 failed (98: Address already in use) 2018/11/14 17:15:23 [emerg] 14151#0: still could not bind()看错误信息提示80端口已经被占用，无法重启Nginx服务，查看80端口进程是哪一个，并kill掉后，重启服务成功netstat -ntpl Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 11333/php-fpm: mast tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 10363/nginx: master tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 15636/sshd tcp6 0 0 :::3306 :::* LISTEN 10604/mysqld tcp6 0 0 :::80 :::* LISTEN 10363/nginx: master kill 10363 service nginx restart访问域名后显示WP的安装，我们点击进行填写mysql的用户名和密码数据用户名和密码填写后报错抱歉，我不能写入wp-config.php文件 ......查看wordpress文件夹，发现是权限问题ll /home | grep wordpress drwxr-xr-x 5 nobody 65534 4096 2月 8 2018 wordpress查看用户组grep -E '^(user|group)' /etc/php-fpm.d/www.conf user = apache group = apache设置访问权限chown -R apache:apache /home/wordpress再次访问成功！参开链接：https://laravel-china.org/articles/10803/this-weekend-theres-a-lot-of-pits-on-the-website-for-a-friend-to-dohttps://blog.csdn.net/u011475134/article/details/80222098https://laravel-china.org/articles/17377#296073
前阵子感冒了，不算严重。期间去过趟医院打针吃药。那天是周五，请了一天假，下午回家后吃完药。就觉的特别的困，可能是前几天实在没有睡好，也可能是药效起的作用。这一觉睡了有个9小时。这之间做了一个梦，算是噩梦。但没有突然的惊醒，浑身冷汗。只感觉睡了好久好久，醒后觉的浑身无力。但这个梦却莹莹沥沥。它是一个故事，不知道是从前哪里看的小说还是哪部电影中留下的碎念。所以，我决定将它稍加改动记录下来：一个女孩，外衣深黑色针织衫，里面穿着一件白色衬衫，红色格子百褶裙，柔柔弱弱的印象。在一家咖啡店中，靠窗的位置坐着，像是在完成学业。突然电话响了，应该是一位好友的来电。女孩说：「不知道哦，挺久没联系了，可能不喜欢我了。打算用这种方式分手吧」。没一会就挂了电话，女孩看了会窗外。用力的咳嗽了几下，从包里拿出了一瓶感冒药，看来也是重感冒，倒了两颗药出来，胶囊状的，瓶子上像是写着女孩的名字。拿起桌子上的水杯服了下去。不久，女孩起身准备离开，拿起桌子上的书籍和文件。出了咖啡店。像是去往家的路上，路上的风景似曾相识。有一颗无花果树攀出围墙，果子红红郁郁，似血似肉。女孩到了住处，习惯性的打开楼道门口的信箱，检查是否有来信。翻开信箱盖子，里面一封白色信封静静的躺在黑色的信盒中。女孩邹了下眉头，像是疑问。拿起信封翻看了一下，两面都是空白一片，没有署名，没有地址，没有邮编，是一封匿名信。女孩撕开信封，里面只有一张照片。拿起一看，顿时被吓了一跳，照片也被抖到了地上。地面上的照片中是一个人被烧死的照片，只有上半身，却血肉模糊，狰狞发呕。照片随着画面一步一步放大。（我也吓死了）画面一转，女孩在家中打着电话：「不会是恶作剧吧，太变态了。本来最近重感冒难受的要死，还有那么多门毕业考试要准备。烦死了」「有点害怕唉，要不报警吧？但是这些估计最多也就立个案」「哎呀，真的和他挺久没联系了，估计想用这种方式逼我先提出分手，他不理我，我也不理他，哼」「好呀，好呀，现在我就过去，在这今晚我肯定睡不着」。第二天早上，女孩和好友道了别，应该是回去拿一些重要的东西。再次来到楼道门口，女孩看了下信箱，拍了拍胸口呼了一口气，像是给自己打气。再次打开信箱，这次里面躺着两封信，女孩有些惊讶，拿起信封，一封清晰的印着是什么医师证书的回寄，而另外一封又是和昨天一样，双面空白，又是一封匿名信。女孩犹豫着要不要打开，「又是昨天那样的恶作剧？」，女孩还是撕开了这封匿名信，这次还是一张照片。一只手正在一个昏暗的房间中，拿着一个锤子敲碎着一具尸体的骨架。这次女孩镇定了很多，「我可是学医的，这吓不到我，死变态」，女孩把照片塞了回去，将信封直接扔进了边上的垃圾桶中。第三天早上，女孩整装待发，走出楼道，经过信箱时，突然有些犹豫。但还是慢慢的转身走向信箱，翻开信箱盖子，里面又躺着一份双面空白的匿名信。「我靠，有完没完」，女孩取出了这封新的信，快速的撕开了信封。这次信封中是两张照片。第一张，一只手将骨灰塞进一个像香烟头的小模具中，大拇指手指甲上还涂着鲜红的指甲油。女孩皱了下眉头，拿起另外一张。另一张，则是一个被装满药囊瓶子的特写。女孩突然懵了一下，好像意识到了什么。快速翻起自己包中的感冒药瓶子，和照片做了下比对。女孩干呕了声，将手中的照片和药瓶子扔在了地上，双手捂住了嘴巴，惊恐的退到了墙上。
这个周末上线一个帮朋友做的网站，遇到挺多坑，记录一下
网站上线流程购买服务器，目前选择的是阿里云服务器，选择的是入门型1核1G实例配置SSH连接增加本机ssh连接配置，一般激活实例后，ssh的22端口是默认开放的，可以直接通过root用户进行登录配置部署环境，登录到服务器后，将自己的公钥加入到 ~/.ssh/authorized_keys 配置文件中就可直接通过秘钥进行登录服务器配置服务器系统版本：CentOS Linux release 7.4.1708 (Core)内存：1GCPU：1核硬盘：40G## 一. 安装Mysql5.5因为服务器配置有点低，所以这边选择安装比较低的mysql版本。从CentOS 7.0发布以来，yum源中开始使用mariadb来代替MySQL的安装。即使你输入的是yum install mysql , 显示的也是mariadb的安装内容，因此，如果使用yum安装MySQL的话，就需要去下载官方指定的yum源。网址： https://dev.mysql.com/downloads/repo/yum/。1. 先卸载mariadb，查看mariadb是否已经安装[root@iZbp17dq2xryqoixibq5u1Z ~]# yum list installed | grep mariadb mariadb-libs.x86_64 1:5.5.56-2.el7 @anaconda进行卸载[root@iZbp17dq2xryqoixibq5u1Z ~]# yum -y remove mariadb* Loaded plugins: fastestmirror Resolving Dependencies ...... **省略过程** Removed: mariadb-libs.x86_64 1:5.5.56-2.el7 Dependency Removed: postfix.x86_64 2:2.10.1-6.el7 redhat-lsb-core.x86_64 0:4.1-27.el7.centos.1 Complete!2. 获取yum源和数据库安装，官方指南wget http://repo.mysql.com/yum/mysql-5.5-community/el/6/x86_64/mysql-community-release-el6-5.noarch.rpm #MySQL5.5yum源安装yum源rpm -ivh mysql-5.5-community/el/6/x86_64/mysql-community-release-el6-5.noarch.rpm 安装好yum源后，需要修改一下配置文件，文件路径在 /etc/yum.repos.d/mysql-community.repo，要将5.5的enabled改为1，而5.6的enabled改为0# Enable to use MySQL 5.5 [mysql55-community] name=MySQL 5.5 Community Server baseurl=http://repo.mysql.com/yum/mysql-5.5-community/el/6/$basearch/ enabled=1 gpgcheck=1 gpgkey=file:/etc/pki/rpm-gpg/RPM-GPG-KEY-mysql # Enable to use MySQL 5.6 [mysql56-community] name=MySQL 5.6 Community Server baseurl=http://repo.mysql.com/yum/mysql-5.6-community/el/6/$basearch/ enabled=0 gpgcheck=1 gpgkey=file:/etc/pki/rpm-gpg/RPM-GPG-KEY-mysql # Note: MySQL 5.7 is currently in development. For use at your own risk. # Please read with sub pages: https://dev.mysql.com/doc/relnotes/mysql/5.7/en/ [mysql57-community-dmr] name=MySQL 5.7 Community Server Development Milestone Release baseurl=http://repo.mysql.com/yum/mysql-5.7-community/el/6/$basearch/ enabled=0 gpgcheck=1 gpgkey=file:/etc/pki/rpm-gpg/RPM-GPG-KEY-mysql修改后保存退出，开始安装MySQL。在安装之前，可以查看下是否已有MySQL可安装文件[root@iZbp17dq2xryqoixibq5u1Z ~]# yum repolist enabled | grep "mysql.*-community.*" mysql-connectors-community/x86_64 MySQL Connectors Community 49 mysql-tools-community/x86_64 MySQL Tools Community 61 mysql55-community/x86_64 MySQL 5.5 Community Server 4493. 安装mysql# 安装client，devel，server yum install mysql-community-client mysql-community-devel mysql-community-server安装完毕后，可以查看下当前mysql版本[root@iZbp17dq2xryqoixibq5u1Z ~]# rpm -qi mysql-community-server Name : mysql-community-server Version : 5.5.60 Release : 2.el6 Architecture: x86_64 Install Date: 2018年05月05日 星期六 16:26:00 ......4. 启动mysql执行 service mysqld start 启动mysql[root@iZbp17dq2xryqoixibq5u1Z ~]# service mysqld start Starting mysqld (via systemctl): [ OK ]ok，mysql安装完毕常用命令：systemctl start mysqld #启动mysqldsystemctl stop mysqld #停止mysqldsystemctl restart mysqld #重启mysqldsystemctl enable mysqld #设置开机启动systemctl status mysqld #查看 MySQL Server 状态5. 数据库安全设置设置mysql root账户密码# mysqladmin -u root password 'new password'重新登录mysql报如下错误ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)执行如下命令进行解决[root@iZbp17dq2xryqoixibq5u1Z ~]# systemctl stop mysqld **关闭mysql服务** [root@iZbp17dq2xryqoixibq5u1Z ~]# mysqld --user=root --skip-grant-tables & **关闭skip-grant-tables** [1] 32163 [root@iZbp17dq2xryqoixibq5u1Z ~]# 180505 16:57:08 [Note] mysqld (mysqld 5.5.60) starting as process 32163 ... 180505 16:57:08 [Note] Plugin 'FEDERATED' is disabled. 180505 16:57:08 InnoDB: The InnoDB memory heap is disabled 180505 16:57:08 InnoDB: Mutexes and rw_locks use GCC atomic builtins 180505 16:57:08 InnoDB: Compressed tables use zlib 1.2.3 180505 16:57:08 InnoDB: Using Linux native AIO 180505 16:57:08 InnoDB: Initializing buffer pool, size = 128.0M 180505 16:57:08 InnoDB: Completed initialization of buffer pool 180505 16:57:08 InnoDB: highest supported file format is Barracuda. 180505 16:57:08 InnoDB: Waiting for the background threads to start 180505 16:57:09 InnoDB: 5.5.60 started; log sequence number 1595675 180505 16:57:09 [Note] Server hostname (bind-address): '0.0.0.0'; port: 3306 180505 16:57:09 [Note] - '0.0.0.0' resolves to '0.0.0.0'; 180505 16:57:09 [Note] Server socket created on IP: '0.0.0.0'. 180505 16:57:09 [Note] mysqld: ready for connections. Version: '5.5.60' socket: '/var/lib/mysql/mysql.sock' port: 3306 MySQL Community Server (GPL) mysql -u root mysql **空密码登入** Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.5.60 MySQL Community Server (GPL) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> UPDATE user SET authentication_string=PASSWORD('new password') where USER='root'; **重新设置root密码** Query OK, 4 rows affected (0.00 sec) Rows matched: 4 Changed: 4 Warnings: 0 mysql> FLUSH PRIVILEGES; **刷新设置** Query OK, 0 rows affected (0.00 sec) mysql> quit Bye## 二. 安装PHP环境1. 开始安装PHP和PHP-FPM首先安装EPEL。EPEL即Extra Packages for Enterprise Linux的简称，是为企业级Linux提供的一组高质量的额外软件包yum -y install epel-release安装PHP和PHP-FPMyum -y install php php-fpm查看PHP版本[root@iZbp17dq2xryqoixibq5u1Z ~]# php -v PHP 5.4.16 (cli) (built: Mar 7 2018 13:34:47) Copyright (c) 1997-2013 The PHP Group Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies这时发现PHP版本是5.4的，原因是yum默认的epel-release源太低了，而我需要部署的网站是基于Laravel5.5开发的，环境要求：PHP >= 7.0.0 需要重新安装PHP7PHP OpenSSL 扩展PHP PDO 扩展PHP Mbstring 扩展PHP Tokenizer 扩展PHP XML 扩展删除之前安装的PHP版本yum remove php* php-common我们需要更换下rpm源，搜索epel-release源并删除后进行更新[root@iZbp17dq2xryqoixibq5u1Z ~]# rpm -qa | grep epel epel-release-7-11.noarch [root@iZbp17dq2xryqoixibq5u1Z ~]# rpm -e epel-release-7-11.noarch warning: /etc/yum.repos.d/epel.repo saved as /etc/yum.repos.d/epel.repo.rpmsave [root@iZbp17dq2xryqoixibq5u1Z ~]# rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-release.rpm Retrieving https://mirror.webtatic.com/yum/el7/epel-release.rpm warning: /var/tmp/rpm-tmp.PHnPwl: Header V4 RSA/SHA1 Signature, key ID 62e74ca5: NOKEY Preparing... ################################# [100%] Updating / installing... 1:epel-release-7-5 ################################# [100%] [root@iZbp17dq2xryqoixibq5u1Z ~]# rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm Retrieving https://mirror.webtatic.com/yum/el7/webtatic-release.rpm warning: /var/tmp/rpm-tmp.ohTozh: Header V4 RSA/SHA1 Signature, key ID 62e74ca5: NOKEY Preparing... ################################# [100%] Updating / installing... 1:webtatic-release-7-3 ################################# [100%]重新安装PHP和一些相关扩展yum install php72w-cli.x86_64 php72w-common.x86_64 php72w-gd.x86_64 php72w-ldap.x86_64 php72w-mbstring.x86_64 php72w-pdo.x86_64安装PHP-FPMyum install php72w-fpm再次查看PHP版本[root@iZbp17dq2xryqoixibq5u1Z ~]# php -v PHP 7.2.4 (cli) (built: Mar 30 2018 08:49:13) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies启动PHP-FPMsystemctl start php-fpm systemctl enable php-fpm.service **开机自启动**常用命令：systemctl start php-fpm # 启动systemctl stop php-fpm # 停止systemctl restart php-fpm # 重启systemctl enable php-fpm #开机自启动## 三. 安装Nginx1. 开始Nginxyum install nginx安装完毕后，启动Nginxsystemctl start nginx systemctl enable nginx **系统启动时自动启动Nginx**常用命令：fuser -k 80/tcp # 杀死80端口nginx -s stop # 停止nginx -s reopen # 重启nginx -s reload # 重新载入配置文件## 四. 网站部署1. 生成秘钥ssh-keygen -t rsa提示一直回车就行，将生成的秘钥添加到项目托管的git库网站上，因为我的网站是放在Coding上，我直接添加在了项目部署秘钥2. 克隆项目通过 git clone 命令将项目拉取到服务器上，我这边因为是Nginx，所以我拉取到 /var/www/ 目录下，3. 安装composer[root@iZbp17dq2xryqoixibq5u1Z project_fjylhjjsyxgs]# curl -sS https://getcomposer.org/installer | php All settings correct for using Composer Downloading... Composer (version 1.6.5) successfully installed to: /var/www/project_fjylhjjsyxgs/composer.phar Use it: php composer.phar移动composer.phar文件到/usr/local/bin目录下 ，使命令全局可用，并更换Packagist中国全量镜像mv composer.phar /usr/local/bin/composer composer config -g repo.packagist composer https://packagist.phpcomposer.com通过composer安装项目依赖，但是出现了报错[root@iZbp17dq2xryqoixibq5u1Z project_fjylhjjsyxgs]# composer install Loading composer repositories with package information Installing dependencies (including require-dev) from lock file Your requirements could not be resolved to an installable set of packages. Problem 1 - Installation request for phar-io/manifest 1.0.1 -> satisfiable by phar-io/manifest[1.0.1]. - phar-io/manifest 1.0.1 requires ext-dom * -> the requested PHP extension dom is missing from your system. Problem 2 - Installation request for phpunit/php-code-coverage 5.3.0 -> satisfiable by phpunit/php-code-coverage[5.3.0]. - phpunit/php-code-coverage 5.3.0 requires ext-dom * -> the requested PHP extension dom is missing from your system. Problem 3 - Installation request for phpunit/phpunit 6.5.7 -> satisfiable by phpunit/phpunit[6.5.7]. - phpunit/phpunit 6.5.7 requires ext-dom * -> the requested PHP extension dom is missing from your system. Problem 4 - Installation request for theseer/tokenizer 1.1.0 -> satisfiable by theseer/tokenizer[1.1.0]. - theseer/tokenizer 1.1.0 requires ext-dom * -> the requested PHP extension dom is missing from your system. To enable extensions, verify that they are enabled in your .ini files: - /etc/php.ini - /etc/php.d/bz2.ini - /etc/php.d/calendar.ini - /etc/php.d/ctype.ini - /etc/php.d/curl.ini - /etc/php.d/exif.ini - /etc/php.d/fileinfo.ini - /etc/php.d/ftp.ini - /etc/php.d/gd.ini - /etc/php.d/gettext.ini - /etc/php.d/gmp.ini - /etc/php.d/iconv.ini - /etc/php.d/json.ini - /etc/php.d/ldap.ini - /etc/php.d/mbstring.ini - /etc/php.d/pdo.ini - /etc/php.d/pdo_sqlite.ini - /etc/php.d/phar.ini - /etc/php.d/shmop.ini - /etc/php.d/simplexml.ini - /etc/php.d/sockets.ini - /etc/php.d/sqlite3.ini - /etc/php.d/tokenizer.ini - /etc/php.d/xml.ini - /etc/php.d/zip.ini You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode.Google后发现，php-xml扩展有以上需要的相关软件包yum install php72w-xml.x86_64重新执行composer install命令，依赖下载成功开始配置Nginx配置我本机homestead中的Nginx是通过 /etc/nginx/sites-available 目录设置对应多域名的nginx配置文件，但是不知道服务器上安装的Nginx，却没有这个目录，所以查看了下Nginx.conf文件，发现http模块中有如下一条配置 本机homestead中Nginx.conf ## # Virtual Host Configs ## include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; 服务器上安装的Nginx.conf # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf;那好吧，我估计sites-available也是软连接的conf.d或者sites-enabled目录吧，所以我就直接将官方手册中Nginx配置复制了一份到/etc/nginx/conf.d/域名.conf，修改了一些配置server { listen 80; server_name 域名或公网IP; root 项目地址指向到public目录; add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff"; index index.html index.htm index.php; charset utf-8; location / { try_files $uri $uri/ /index.php?$query_string; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } error_page 404 /index.php; location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; **这里有个坑下面讲** fastcgi_index index.php; include fastcgi_params; } location ~ /\.(?!well-known).* { deny all; } }配置完毕，保存退出，通过域名访问，发现报502错误，查看下Nginx的错误日志，发现报如下错误2018/05/06 20:17:37 [crit] 5898#0: *66 connect() to unix:/var/run/php/php7.2-fpm.sock failed (2: No such file or directory) while connecting to upstream,简单的讲下，php-fpm.sock文件就是让Nginx和PHP-FPM的进程间进行通信的文件，具体的含义，这边就不做详细介绍了。进这个目录查看下是否存在这个目录或文件，发现两个问题：目录错误，不是/var/run/php，而是/var/run/php-fpmphp7.2-fpm.sock这个文件未生成未生成原因：php5.3之后的版本，php-fpm.conf里的listen的默认配置是127.0.0.1:9000，也就是tcp的方式，不会生成php-fpm.sock。因为这次上线的网站没有什么并发量，unix socket方式要比tcp的方式快而且消耗资源少，所以我还是采用unix socket方式。定位到问题后，修改下 /etc/php-fpm.d/www.conf，也就是php-fpm的配置文件，关闭原来的listen方式，然后重启下php-fpm;listen = 127.0.0.1:9000 listen = /var/run/php-fpm/php7.2-fpm.sock这个时候，由于职业习惯，想把Nginx也重启下，然后就又碰到了一个问题[root@iZbp17dq2xryqoixibq5u1Z project_fjylhjjsyxgs]# nginx -s stop [root@iZbp17dq2xryqoixibq5u1Z project_fjylhjjsyxgs]# nginx -s reload nginx: [error] open() "/run/nginx.pid" failed (2: No such file or directory)这应该是因为把Nginx进程杀死后pid丢失了，下一次再开启nginx -s reload时无法启动。再次面向Google编程，发现还有挺多人碰到这个问题，所以解决方法马上就能搜索到了，执行如下命令nginx -c /etc/nginx/nginx.conf nginx -s reloadok，接着Navicat远程连接到服务器数据库，source下数据库完毕。现看起来应该是可以跑起网站来了。再次访问域名，发现还是502，再次查看Nginx日志，报如下错误：2018/05/06 20:37:00 [crit] 6078#0: *1 connect() to unix:/var/run/php-fpm/php7.2-fpm.sock failed (13: Permission denied) while connecting to upstream,和上面报错看起来差不多，但是这次主要问题出在跑Nginx的用户是Nginx，而php-fpm.sock这个文件，监听的Nginx用户没有该权限，导致Nginx无法访问php-fpm.sock这个文件，自然监听就失去了效果，再次修改php-fpm配置文件和重启下php-fpm; Set permissions for unix socket, if one is used. In Linux, read/write ; permissions must be set in order to allow connections from a web server. Many ; BSD-derived systems allow connections regardless of permissions. ; Default Values: user and group are set as the running user ; mode is set to 0660 listen.owner = nginx listen.group = nginx listen.mode = 0660重新访问下域名，发现访问任何路由都是白屏，这次状态码都是200了，但是没有任何输出，再次面向Google编程……发现问题：由于nginx与php-fpm之间的一个小bug，会导致这样的现象： 网站中的静态页面 .html 都能正常访问，而 .php 文件虽然会返回200状态码， 但实际输出给浏览器的页面内容却是空白。 简而言之，原因是nginx无法正确的将 *.php 文件的地址传递给php-fpm去解析， 相当于php-fpm接受到了请求，但这请求却指向一个不存在的文件，于是返回空结果。 为了解决这个问题，需要改动nginx默认的fastcgiparams配置文件在 /etc/nginx/fastcgi_params 文件的最后增加两行：fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_script_name; 再再再次访问域名，终于正常显示了，但是页面上又出现了新的错误：could not find driver（select * from users where deleted = 0）任何有sql查询的页面都报如上错误，这个错误多半是因为pdo_mysql未打开或者未安装此模块造成，执行 php -m 发现还真没装，安装php72w-mysql的又遇到一个坑yum install php72w-mysql报如下错误，说缺少libmysqlclient.so.18依赖...... error: package: php72w-mysql requires: libmysqlclient.so.18(libmysqlclient_18)(64bit) Available: 1:mariadb-libs-5.5.52-1.el7.x86_64 (base) libmysqlclient.so.18(libmysqlclient_18)(64bit) ......这就很奇怪了，查看用户库文件目录内libmysqlclient.so.18已经存在[root@iZbp17dq2xryqoixibq5u1Z ~]# ll /usr/lib64/mysql/libmysqlclient.so.18 libmysqlclient.so.18 libmysqlclient.so.18.1.0这个坑花了一个小时，Google多次尝试无果后，认真思考下可能的原因，想了想可能是mysql版本的问题，修改下 /etc/yum.repos.d/mysql-community.repo 配置文件，将5.6的enabled设为1，5.5设为0，更新Mysql版本后，再次执行 yum install php72w-mysql 成功安装pdo_mysql模块…...## 至此，网站访问终于成功！后续的部署优化，另外开篇记录。
一. What is composer?是 PHP 用来管理依赖（dependency）关系的工具。你可以在自己的项目中声明所依赖的外部工具库（libraries），Composer 会帮你安装这些依赖的库文件。 ---- Composer文档这边的依赖可以理解为各种开发包或者插件，当我们在项目中要使用第三方工具库的时候，我们往往要从官网或者一些别的其他途径来获取源文件，并放入到自己的项目中，在使用的时候，通过手动require的方式引用。当然我们大部分会通过写一个自动加载方法来进行require。但当我们使用比较大的第三方工具库时，可能它的其中又去依赖了更多别的第三方包。而且往往有时候工具库的版本更新可能会不兼容旧版本，我们手动去进行依赖那将会是一件痛苦的事情。 那么Compser能为我们解决哪些问题：a) 你有一个项目依赖于若干个库。b) 其中一些库依赖于其他库。c) 你声明你所依赖的东西。d) Composer 会找出哪个版本的包需要安装，并安装它们（将它们下载到你的项目中）。二. 开始使用Composer系统要求: 运行 Composer 需要 PHP 5.3.2+ 以上版本。 安装Composer: Composer文档-安装Composer的包版本符号composer的依赖声明通常都写在项目根目录下的composer.json文件中，通过JSON format的方式进行编写，就像这样子：{ "require": { "monolog/monolog": "1.0.*" } }require是指定Key，我们需要做的，就是在这个指定key中增加我们需要的依赖包 ("monolog/monolog") 和指定的版本 ("1.0.*"),那么在使用前，首先我们需要知道composer中是怎么声明我们需要依赖的包版本的:point_right:点击链接查看Composer install和update如果composer已经安装成功的话，可以直接在命令行中执行 "composer" 命令来查看命令列表，但在大部分的时候，使用频率最高的是install和update命令，顾名思义就是使用composer安装和更新依赖包。比如我们已经在项目的composer.json中声明了依赖{ "require":{ "mustache/mustache":"2.8.0" } }在命令行中直接执行 "composer install"，就能直接将这个工具库依赖到我们系统中$ composer install Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 1 install, 0 updates, 0 removals - Installing mustache/mustache (v2.8.0): Downloading (100%) Writing lock file Generating autoload files再打开项目文件夹，就能发现新增了vendor文件夹和composer.lock文件，vendor目录存放是composer的自动加载文件和我们刚刚下载的工具库，composer.lock文件是在安装依赖后，composer将把安装时确切的版本号列表(composer.json定义的)写入composer.lock 文件中，锁定项目所使用的包版本。这样做的意义是：在提交项目的时候，请将lock文件也提交，这样在团队开发中，如果有别的成员进入开发，建立项目时都将下载与指定版本完全相同的依赖，减轻潜在的部署错误。当我们的项目搁浅很久，在几个月后重新安装项目，也能正常的继续工作，尽管可能项目的依赖包已经发布了很多新版本。所以，如果已经存在lock文件的话，我们要更新在使用的依赖，这时候就需要执行 "composer update" 命令进行更新，update命令会从新读取composer.json的文件，更新所声明依赖版本并重新读写composer.lock文件。这边我将composer.json中的依赖版本声明为 "v2.9.0"执行命令$ composer update Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 0 installs, 1 update, 0 removals - Updating mustache/mustache (v2.8.0 => v2.9.0): Loading from cache Writing lock file Generating autoload files可以通过 "composer show -i" 命令查看当前已经安装的依赖包版本$ composer show -i mustache/mustache v2.9.0 A Mustache implementation in PHP.三. 在项目中使用依赖包composer提供了自动加载文件来提供自动加载支持，我们只要在项目的入口文件中添加这行代码<?php require "vendor/autoload.php"; $obj = new Mustache_Engine(); $obj->render('Hello world');
一. 依赖注入和控制反转是什么？名词解释：IoC控制反转 Inversion of Control依赖关系的转移依赖抽象而非实践DI依赖注入 Dependency Injection不必自己在代码中维护对象的依赖容器自动根据配置，将依赖注入指定对象Container管理对象的生成、资源取得、销毁等生命周期建立对象与对象之间的依赖关系启动容器后，所有对象直接取用，不用编写任何一行代码来产生对象，或是建立对象之间的依赖关系------------以上引用自网络二. IoC代码演示高层应用程序需要调用底层模块接口,导致高层应用程序对低层模块产生依赖。<? // 高层类 class Order { private $track; public function __construct() { $this->track = new sf(); //顺丰快递 } public function query() { return $this->track->select(); } } // 底层类，快递接口 class sf { public function select { return "快递已送达"; } } $order = new Order(); $order->query(); 假设我们有一个订单类，需要跟踪订单的物流信息，物流目前是和顺丰快递进行合作。但后因种种原因，需要迁移快递物流平台到圆通上去,那现在因为产生了物流接口依赖，程序无法重用，并且必须要修改或者新增圆通快递接口。这就是由于低层模块变化导致高层也跟着变化，不好的设计。而正如上面的IoC解释控制反转 Inversion of Control依赖关系的转移依赖抽象而非实践程序不应该依赖于具体的实现，而是要依赖抽象的接口。如下：<?php // 物流平台接口 interface trackBox { public function select(); } // 高层类 class Order { private $track; public function setTrack($track) { $this->track = $track; } public function query() { return $this->track->select(); } } // 底层 顺丰 class sf implements trackBox { public function select() { return "顺丰快递已送达"; } } // 底层 圆通 class yt implements trackBox { public function select() { return "圆通快递已送达"; } } $order = new Order(); $order->setTrack(new sf()); $order->query(): //顺丰快递已送达 $order->setTrack(new yt()); $order->query(): //圆通快递已送达 这样就将原来的物流查询模块对程序的控制权转移到trackBox接口上，让order类和各种物流接口类都依赖于trackBox,这样就实现了控制反转。面对变化，高层不用修改一行代码，不再依赖低层，而是依赖注入，这也就引出了(依赖注入)DI。 依赖注入的方式有很多，但是主要思想就是如上所示，我们将一个依赖通过注入的方式进行使用。而不是直接将依赖写入被依赖中进行具体的实现。三. 依赖注入容器 Dependency Injection Container那我们接下来继续思考，如果此后业务扩张，合作的物流平台越来越丰富，那么高层程序依赖的物流接口就会越来越多，我们就需要创建的依赖接口实例也会越来越多，这样就很不利于后期的维护 //底层物流接口 class sf implements trackBox{ ... } //顺丰 class yt implements trackBox{ ... } //圆通 class zt implements trackBox{ ... } //中通 class yd implements trackBox{ ... } //韵达 class ems implements trackBox{ ... } //EMS //依赖注入 $order = new Order(); $order->setTrack(new sf()); $order->select(): //顺丰快递已送达 $order->setTrack(new yt()); $order->select(): //圆通快递已送达 $order->setTrack(new zt()); $order->select(): //中通快递已送达 $order->setTrack(new yd()); $order->select(): //韵达快递已送达 $order->setTrack(new ems()); $order->select(): //EMS快递已送达 这个时候，我们有一种比较优雅的设计方案就是采用"工厂模式"，工厂模式，个人理解就是一个类所依赖的外部实例，可以被一个或多个"工厂"创建的这样一种开发模式我们不手动进行创建依赖实例，而是通过工厂去创建依赖实例，我们需要做的只是通过工厂拿到我们需要用到的依赖实例<? // 工厂类 class TrackFactory { public function makeTrack($trackName) { switch ($trackName) { case 'sf': return new sf(); case 'yt': return new yt(); case 'zt': return new zt(); case 'yd': return new yd(); case 'ems': return new ems(); } // return new $trackName(); } } // 高层类 class Order { private $track; public function __construct(array $tracks) { // 初始化工厂类 $trackFactory = new TrackFactory(); // 通过工厂类提供的方法制造所需要的物流平台 foreach ($tracks as $trackName) { $this->$track[] = $trackFactory->makeTrack($trackName); } } public function query($trackName) { return $this->track[$trackName]->select(); } } $Order = new Order(['sf','yd','ems','zt',]); $Order->query('sf'); $Order->query('yd'); $Order->query('ems'); 尽管工厂模式让我们的代码变得优雅了一点，但是我们又回到了开头的错误中来，我们现在对工厂类进行了依赖,并且在物流接口愈加丰富后，工厂类也会慢慢变的冗长而不利于维护，那我们要怎么才能设计出一套即优雅又松耦合的应用程序呢？这个时候就需要有容器这个概念Container管理对象的生成、资源取得、销毁等生命周期建立对象与对象之间的依赖关系启动容器后，所有对象直接取用，不用编写任何一行代码来产生对象，或是建立对象之间的依赖关系<? // 容器类 class Container { protected $binds; public function bind($service, $instance) { if ($concrete instanceof Closure) { $this->binds[$service] = $instance; } } public function make($service, $parameters) { return call_user_func_array([$this->binds[$service],], $parameters); } } // 高层类 class Order { private $track; public function __construct($track) { $this->track = $track; } public function query() { return $this->track->select(); } } $container = new Container(); $container->bind('sf', function($container) { return new sf(); }); $container->bind('Order', function($container) { return new Order(); }); $Order = $container->make('Order','sf');
一. 安装redis服务器使用Homebrew安装redis可以减少大量的安装和配置的工作量。执行 brew install redis 安装redis常用命令redis-server #启动redis服务器redis-cli # redis客户端redis-server --port 6380 #Redis 默认端口是6379，也可以换个端口号启动redis-cli shutdown #关闭redis，服务端会断开所有客户端的连接，然后根据配置执行持久化，最后退出。二. 安装php-redis扩展php默认不支持redis，需要进行编译才能使用。下载源码编译 php官方扩展库链接将redis-4.0.2.tgz（写这篇文章时的最新版本）下载到本地执行tar -xzf命令，解压.tgz 后缀的文件进入到redis-4.0.2文件夹中，依次执行如下命令：phpize./configuremakesudo make install在php.ini中启用redis添加 extension=redis.so;重启php-fpm和nginx三. 在PHP中使用redis连接到 redis 服务php代码<?php //连接本地的 Redis 服务 $redis = new Redis(); $redis->connect('127.0.0.1', 6379); echo "Connection to server sucessfully";//查看服务是否运行 echo "Server is running: " . $redis->ping();?>执行脚本，输出结果为：Connection to server sucessfully Server is running: PONG