书写技术成长之路

Centos安装配置Supervisod

EPEL是Fedora官方维护的Linux企业扩展库,提供高质量的软件库,里面包含大量开源的工具集。

第一步,开启EPEL Repository,下载并安装EPEL。

  • wget http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-10.noarch.rpm

  • rpm -ivh epel-release-7-10.noarch.rpm

第二步,检查EPEL是否开启成功 yum repolist

第三步, 查找supervisord yum --enablerepo=epel info zabbix

第四步, 安装supervisord yum --enablerepo=epel install zabbix

安装完后后会有两个命令,一个supervisord和supervisorctl,supervisord是服务端进程,supervisorctl是管理服务器端进程的,可以重新加载配置,重启,查看进程状态等。

Supervisord配置

;[program:laravel-worker]
;command=php artisan queue:work --timeout=120              ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s) 多进程的话需要设置为%(program_name)s_%(process_num)02d
;numprocs=1                    ; number of processes copies to start (def 1) 进程数量
;directory=/tmp                ; directory to cwd to before exec (def no cwd)
;umask=022                     ; umask for process (default None)
;priority=999                  ; the relative start priority (default 999) 优先级,值越低优先级越高,越先启动
;autostart=true                ; start at supervisord start (default: true) 如果是true,当supervisor启动时,程序将会自动启动
;autorestart=true              ; retstart at unexpected quit (default: true) 是否自动重启
;startsecs=10                  ; number of secs prog must stay running (def. 1)
;startretries=3                ; max # of serial start failures (default 3)
;exitcodes=0,2                 ; 'expected' exit codes for process (default 0,2)
;stopsignal=QUIT               ; signal used to kill process (default TERM)
;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
;user=chrism                   ; setuid to this UNIX account to run the program
;redirect_stderr=true          ; redirect proc stderr to stdout (default false)
;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)
;stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
;stdout_events_enabled=false   ; emit events on stdout writes (default false)
;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10     ; # of stderr logfile backups (default 10)
;stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
;stderr_events_enabled=false   ; emit events on stderr writes (default false)
;environment=A=1,B=2           ; process environment additions (def no adds)
;serverurl=AUTO                ; override serverurl computation (childutils)
参考

https://www.tecmint.com/how-to-enable-epel-repository-for-rhel-centos-6-5/

https://www.cyberciti.biz/faq/installing-rhel-epel-repo-on-centos-redhat-7-x/

https://support.rackspace.com/how-to/install-epel-and-additional-repositories-on-centos-and-red-hat/

https://my.oschina.net/crooner/blog/395069

Linux漂亮的工具集

参考

MySQL主要参数设置

innodb_buffer_pool_size参数

InnoDB用来设置缓存它的数据和索引的内存缓冲区大小,减少I/O。可以设置为服务器内存的70%-80%大小, 注意单位为字节

innodb_log_file_size参数

日志文件的大小,建议设置为innodb_log_file_size = 512M,通常是buffer pool的1/4。

max_connections参数

mysql允许的最大连接数。如果你遇到了Too many connections错误,你就需要考虑调整这个参数了,但是过大的连接数会占用过多的内存导致 系统不可用,你可以考虑在应用层使用连接池或者在MySQL层使用线程池。

slow_query_log参数

设置是否开启慢查询日志,你应当在生产环境开启这个配置slow_query_log=1

slow_query_log_file参数

设置记录慢查询日志的文件路径

long_query_time参数

long_query_time设置慢查询的时间

参考

https://www.percona.com/blog/2014/01/28/10-mysql-performance-tuning-settings-after-installation/

http://www.codingpedia.org/ama/optimizing-mysql-server-settings/

php-fpm优化配置

一直以来很少关注PHP-FPM的配置,偶然一天看到一篇技术文章,讲述的是PHP-FPM占用的大量的内存和CPU,如何优化的问题。

/etc/php-fpm.conf.default中 PHP-FPM的默认配置是pm = dynamic, 也就是动态的分配php-fpm的子进程,这就导致了 一些分配的进程没有被使用,只是等在那里,所以占用了内存。

文章里提到的最重要的就是改变这种动态分配子进程的方式,改用在需要时才分配,大大节约了内存和CPU

# 优化前的配置
pm = dynamic
pm.max_children = 75
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500

# 优化后的配置
pm = ondemand
pm.max_children = 75
pm.process_idle_timeout = 10s
pm.max_requests = 500

参考

How to reduce PHP-FPM (php5-fpm) RAM usage by about 50%

A better way to run PHP-FPM

Linux常用运维命令

  • 查看端口占用情况 netstat -tulpn

  • 查看最占CPU和内存的进程 ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head

  • 显示内存和虚拟存储器使用情况 free -h

  • 显示CPU信息 核数,架构,一级,二级缓存等 lscpu

  • 压缩 tar -czf home.tar.gz filename

  • 解压缩 tar -zxvf filename.tar.gz

  • 查看文件大小-由大到小 du -chs --time /var/www/* | sort -rn | head
    一款强大的工具是ncdu

  • Linux强制另一终端连接退出

  1. 首先用who命令查看都有哪个终端连接
  2. 用ps命令查看终端占用的进程 sudo ps -ft pts/1
  3. 强制退出 sudo kill -9 6022 6356 6357

MySQL之细节决定成败

今天无意中查下数据,发现了个奇怪的现象,在一条几十万数据的表中分明已经建了索引,还是使用了全表扫描。

在members表中有一个记录会员手机号的phone字段,由于经常根据手机号来进行查找而且数据量也开始上来了,就在phone表中加了个普通索引, phone的类型是varchar(20), 可是今天查找的时候竟然使用了全表扫描,可是看了表中的索引,确实已经在phone字段上建了索引,很奇怪为什么会出现这种情况。

最后发现这是由于查找写的值类型和字段的类型不一样导致MySQL无法使用索引优化.

WechatIMG102.jpeg

看到区别了吗,由于我在查询的时候phone=134321直接是integer类型的,而phone是varchar类型的,就导致最后查询的时候没有用到索引,但是却出现在了possible_keys中,而当使用phone='134321'时,执行查询就可以用到索引,rows便是最明显的区别。

Docker入门

安装Docker

在RedHat 7上只能安装Docker EE版本,这里使用阿里云的源来进行安装。

执行命令: curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh -

安装完成后,如果要以非root身份运行docker, 需要把用户加入docker用户组, sudo usermod -aG docker ec2-user

然后启动docker服务 sudo service docker start

查看docker的信息 docker info

安装个经典的hello world,docker run hello-world , 如果成功,就说明docker可以正常工作了。

进入某个container docker exec -it container_name /bin/bash

安装docker-compose

sudo -i
curl -L https://github.com/docker/compose/releases/download/1.15.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
参考

https://docs.lvrui.io/2017/04/15/快速安装Docker/

Centos 设置交换文件失败的解决办法

由于安装MySQL的时候内存不足导致安装失败,所以需要添加交换文件来增加内存。

  1. 首先用swapon -s来查看是否已经有交换空间, 还可以通过free -m来查看,因为我的是空,所以显示如下 swap1

  2. 创建一个4G大小的交换空间 sudo fallocate -l 4G /swapfile

  3. 查看刚才创建的交换文件是否成功 ls -lh /swapfile

  4. 改变虚拟交换空间的权限 sudo chmod 600 /swapfile

  5. 将该文件标记为用于交换空间 sudo mkswap /swapfile

  6. 使用交换空间 sudo swapon /swapfile, 这个时候报错了 swap2

经过一番搜索,发现fallocate命令并不是真实的创建了物理空间, 所以需要使用下面的命令来创建真实的地址 sudo dd if=/dev/zero of=/swapfile count=4096 bs=1MiB

  1. 再次执行sudo mkswap /swapfilesudo swapon /swapfile就已经成功了 swap3

参考地址

  1. https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s2-swap-creating-file.html

  2. https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-centos-7

  3. https://unix.stackexchange.com/questions/294600/i-cant-enable-swap-space-on-centos-7

大话PHP SESSION

说起session,作为一名后台开发程序猿,无人不知无人不晓。其实开发以来,只知道个大概原理,这次要详细记录下来。

session的由来

说起session的由来就必须先从HTTP说起了,由于HTTP协议是无状态的,所以并不能识别这个请求每次是谁发送的, 比如你这次发请求往购物车里添加商品,然后你又添加一个商品,由于HTTP的无状态,所以根本不能识别还是你添加的, 它把每次请求都视为不同的,这样就不能记录用户相关的信息了,更别说现在做什么智能推荐等等了。

为了能记录这些状态,一些先驱,前辈便发明了session和cookie这对兄弟。当你第一次请求服务器的时候,就给你分配一个唯一的session_id, 在服务端保存这个session_id,并在你的浏览器设置cookie,比如这个cookie名叫SESSIONID。当你下次发送请求的时候浏览器就会自动带上这个cookie发送到服务器端,服务器端查找这个SESSIONID,如果找到就可以识别这个就是你了。比如你不登录也能往购物车里添加商品,每次就是根据这个SESSIONID来维护购物车的状态,当你登录了就自动把购物车里商品信息记录到你的用户下。还有你不登录的时候一些APP的智能推荐新闻等,即使你未登录,也会在客户端和服务端有一个唯一标识你信息的ID。

如何设置30天自动登录呢?

30天自动登录,以前想的就是你登录成功的时候,就用setcookie把过期时间设置为30天的时间。但是这个只是设置cookie的有效期,跟服务端的session有效期是两个独立的概念。比如你手动把浏览器的cookie清除了,就登录不上去了,这只是你浏览器的SESSIONID不存在才导致不能登录,并不是SESSION也失效了,你看到的未必是你看到的~。如果你能伪造之前的COOKIE并发送到服务器端,还是可以登录的,因为这个时候服务端的SESSION还是有效的,并没有被回收。

那么SESSION的30天有效期怎么设置呢?

首先不是setcookie那么简单的就解决了,当然setcookie设置30天的有效期是必要的,但是还要设置服务端session的有效期。 stackoverflow的大神是这么说的

  • session.gc_maxlifetime should be at least equal to the lifetime of this custom expiration handler (1800 in this example);

  • if you want to expire the session after 30 minutes of activity instead of after 30 minutes since start, you'll also need to use setcookie with an expire of time()+60*30 to keep the session cookie active.

大意是说你要用session.gc_maxlifetime来设置session的最大生命周期,超过设个时间就会被垃圾回收, 然后在你的程序里,session_start的时候要设置一个last_activity值,记录最后更新的时间,如果这个值还存在,并且距离当前小于30天的 就表面还有效,就更新最后的更新时间,否则就销毁这个sesion,以此来实现30天自动登录的功能。

闲扯

现在更多的使用JWT(Json Web Token)来做状态标识了,因为一下几点使得JWT更适合当今的开发

  • SESSION默认是使用文件存储的,当访问量大和数据量大的时候,这会成为性能瓶颈
  • SESSION在负载均衡的时候会比较麻烦,当然可以使用Redis,Memcache等来解决(也能解决上面的问题)
  • SESSION在前后端分离模式下就显得更不适用了
  • JWT直接保存相关用户信息,还可以使用签名来保证安全,不用服务端保存这些信息,节省了空间,也解决了SESSION的性能瓶颈问题

参考地址

https://stackoverflow.com/questions/520237/how-do-i-expire-a-php-session-after-30-minutes

http://www.laruence.com/2012/01/10/2469.html