虚拟机-centos7安装VBoxGuestAdditions出错

VBoxGuestAdditions 是Virtual Box虚拟机的辅助功能软件,可以实现 虚拟机的共享文件夹、共享剪切板 等功能。

没有安装Virtual Box增强功能Guest Additions的虚拟机操作很不方便,比如:

  • 虚拟机的分辨率最大只有1024×768;
  • 鼠标被虚拟机捕获后要按右Ctrl键才能释放,否则只能再虚拟机里移动;
  • 剪贴板不能共享

通过虚拟机的菜单栏–>devices–>Insert Guest Additions CD image  安装

Kernel headers not found for target kernel

安装出现错误,查看日志文件  /var/log/vboxadd-install.log

VirtualBox Guest Additions: Starting.
VirtualBox Guest Additions: Building the VirtualBox Guest Additions kernel 
modules.  This may take a while.
VirtualBox Guest Additions: To build modules for other installed kernels, run
VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup <version>
VirtualBox Guest Additions: or
VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup all
VirtualBox Guest Additions: Kernel headers not found for target kernel 
3.10.0-862.11.6.el7.x86_64. Please install them and execute
  /sbin/rcvboxadd setup
modprobe vboxguest failed
The log file /var/log/vboxadd-setup.log may contain further information.

发现是 kernel header 文件没有找到

### 这里就需要安装 kernel-devel 和 kernel-headers 
### 然后因为要编译Guest Additions模块,所以需要 gcc make //安装GCC就行,后面命令行安装有反馈
###【我这里好像没有装cmake 也可以啊,到底是不是需要编译以后再探讨吧】
yum install kernel-headers kernel-devel gcc make -y


### 编译完后 重启电脑
reboot

### 查看当前安装的 内核开发环境  版本
rpm -qa|grep -e  kernel-devel  -e  kernel-headers 

kernel-devel-3.10.0-327.18.2.el7.x86_64
kernel-headers-3.10.0-327.18.2.el7.x86_64

### 查看系统 中使用的内核版本
uname -r
3.10.0-327.18.2.el7.x86_64

成功安装好后,就可以继续执行Guest Additions的安装了。

/sbin/rcvboxadd setup

unable to find the sources of your current Linux kernel

别人遇到的错误,记录一下:

/tmp/vbox.0/Makefile.include.header:112: *** Error: unable to find the sources of your current Linux kernel. Specify KERN_DIR= and run Make again.  Stop.
Creating user for the Guest Additions.
Creating udev rule for the Guest Additions kernel module.
查询kernel-devel版本是3.10.0-514.26.2.el7.x86_64,而Linux内核版本是3.10.0-514.el7.x86_64,确实不一致。如果安装CentOS时选择了Development Tools组,kernel-devel版本和Linux内核版本是匹配的,则不会出现这个问题。
$ rpm -qa | grep kernel-devel
kernel-devel-3.10.0-514.26.2.el7.x86_64

$ uname -r
3.10.0-514.el7.x86_64

可以使用下面两个命令中的一个安装和Linux内核版本匹配的kernel-devel
$ sudo yum install -y "kernel-devel-uname-r == $(uname -r)"
$ sudo yum install -y kernel-devel-3.10.0-514.el7
然后再次安装Guest Additions成功
$ cd /run/media/centos/VBOXADDITIONS_5.1.22_115126
$ sudo sh ./VBoxLinuxAdditions.run

 

补充我实现的简便方法
确实是犹豫内核版本不一样导致无法挂载共享
1、登入linux系统查看内核版本 $ uname -r
2、进行系统升级,yum update, 升级结果就能看到内核已经升级了 3.10.0-862.2.3.el7.x86_6
3、这个时候直接安装 yum install gcc kernel-devel kernel-headers dkms make bzip2
查看kernel-devel 版本  kernel-devel-3.10.0-862.2.3.el7.x86_64

这样就内核一致了
4、最后关机
5、利用virtualbox 给这个虚拟机添加 VBoxGuestAddisions 包后缀iso
6、这时候vagrant up就会自动安装了


命令行模式安装

安装增强功能,需要先安装这些

#yum install kernel-headers
#yum install kernel-devel
#yum install gcc* 
#yum install make

通过虚拟机的菜单栏–>devices–>Insert Guest Additions CD image  安装:

1、有图形界面和windows一样,双击CD里面的文件执行;
2、命令行模式先将cdrom挂载到mnt目录下,这里的cdrom也需要到dev目录下去查看验证是否这个文件,否则也会有错误。

[root@localhost ~]# mount /dev/cdrom  /mnt
mount: /dev/sr0 is write-protected, mounting read-only
[root@localhost ~]# cd /mnt
[root@localhost mnt]# ls
AUTORUN.INF  runasroot.sh                       VBoxSolarisAdditions.pkg
autorun.sh   TRANS.TBL                          VBoxWindowsAdditions-amd64.exe
cert         VBoxDarwinAdditions.pkg            VBoxWindowsAdditions.exe
NT3x         VBoxDarwinAdditionsUninstall.tool  VBoxWindowsAdditions-x86.exe
OS2          VBoxLinuxAdditions.run
[root@localhost mnt]# 

执行安装程序,遇到问题

[root@localhost mnt]# ./VBoxLinuxAdditions.run
Verifying archive integrity... All good.
Uncompressing VirtualBox 6.0.10 Guest Additions for Linux........
VirtualBox Guest Additions installer
Copying additional installer modules ...
Installing additional modules ...
VirtualBox Guest Additions: Starting.
VirtualBox Guest Additions: Building the VirtualBox Guest Additions kernel 
modules.  This may take a while.
VirtualBox Guest Additions: To build modules for other installed kernels, run
VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup <version>
VirtualBox Guest Additions: or
VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup all
VirtualBox Guest Additions: Kernel headers not found for target kernel 
3.10.0-957.21.3.el7.centos.plus.i686. Please install them and execute
  /sbin/rcvboxadd setup
modprobe vboxguest failed
The log file /var/log/vboxadd-setup.log may contain further information.
[root@localhost mnt]# 

安装kernel-devel 和 kernel-headers

yum install kernel-devel kernel-headers

再次执行发现需要GCC

[root@localhost mnt]# ./VBoxLinuxAdditions.run
Verifying archive integrity... All good.
Uncompressing VirtualBox 6.0.10 Guest Additions for Linux........
VirtualBox Guest Additions installer
Removing installed version 6.0.10 of VirtualBox Guest Additions...
Copying additional installer modules ...
Installing additional modules ...
VirtualBox Guest Additions: Starting.
VirtualBox Guest Additions: Building the VirtualBox Guest Additions kernel 
modules.  This may take a while.
VirtualBox Guest Additions: To build modules for other installed kernels, run
VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup <version>
VirtualBox Guest Additions: or
VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup all
VirtualBox Guest Additions: Building the modules for kernel 
3.10.0-957.21.3.el7.centos.plus.i686.

This system is currently not set up to build kernel modules.
Please install the gcc make perl packages from your distribution.
modprobe vboxguest failed
The log file /var/log/vboxadd-setup.log may contain further information.
[root@localhost mnt]# 

继续安装 gcc

yum install gcc

再执行VBoxGuestAdditions安装,成功。

[root@localhost mnt]# ./VBoxLinuxAdditions.run
Verifying archive integrity... All good.
Uncompressing VirtualBox 6.0.10 Guest Additions for Linux........
VirtualBox Guest Additions installer
Removing installed version 6.0.10 of VirtualBox Guest Additions...
Copying additional installer modules ...
Installing additional modules ...
VirtualBox Guest Additions: Starting.
VirtualBox Guest Additions: Building the VirtualBox Guest Additions kernel 
modules.  This may take a while.
VirtualBox Guest Additions: To build modules for other installed kernels, run
VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup <version>
VirtualBox Guest Additions: or
VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup all
VirtualBox Guest Additions: Building the modules for kernel 
3.10.0-957.21.3.el7.centos.plus.i686.
[root@localhost mnt]# 

说明

kernel.i686 : Linux 内核(Linux 操作系统的核心)
kernel-devel.i686 : 用来构建与内核匹配的内核模块的开发软件包。

yum search mysql 则会出现有i686,i386,x86_64的等,我就试了x86_64
总结来说(借用别人的):i386架构对应的是32位系统、而i686是i386的一个子集,i686仅对应P6及以上级别的CPU,
i386架构则广泛适用于80386以上的各种CPU;x86_64架构支持64位系统。

 查看

[root@localhost mnt]# cat /proc/version
Linux version 3.10.0-957.21.3.el7.centos.plus.i686 ([email protected]) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Tue Jun 18 18:05:09 UTC 2019
[root@localhost mnt]# 

创建共享文件夹

1、在windows 下共享文件夹,给个共享路径,名称设置为project,自动挂载,固定分配

2、在centos中 创建共享文件夹,挂载共享文件夹,project为上面创建共享的文件夹名称

[root@localhost mnt]# mkdir /usr/os_share
[root@localhost mnt]# mount -t vboxsf project /usr/os_share
[root@localhost mnt]# ls /usr/os_share
share_ok_file.txt
[root@localhost mnt]# 

 


参考:
https://www.cnblogs.com/mylinux/p/5612168.html
https://www.jianshu.com/p/7c556c783bb2
https://blog.csdn.net/blueney/article/details/80236204
https://blog.csdn.net/blueney/article/details/80236204

建站通用-开源富文本编辑器所见即所得wysiwyg-editor

开发博客时,可以集成的 文章编辑器

https://github.com/quilljs/quill

https://github.com/tinymce/

https://github.com/ckeditor/ckeditor5

https://github.com/froala/wysiwyg-editor

其他富文本编辑器:https://segmentfault.com/q/1010000002897384

上面已经回答了,http://simditor.tower.im/,或者kindeditor,ueditor

uEditer 之前用的感觉不是很好。现需要更换,求推荐好用,且兼容性好
比如本站中的富文本编辑器。
主要需求为:能上传图片,排版方便,添加附件。

ckeditor,可以通过js调用他们的API来完成对编辑器的自定义,提供插件也比较丰富。比如可以自定义段落是用p、div或者是br标签来分割?也可以定义内容过滤器指定源码中可以用哪些标签,每个标签允许出现什么属性以及是否允许出现style样式。

官方文档里讲的很详细http://docs.ckeditor.com/ 我最近一直在用,功能很强大,建议下载完整包然后再根据自己的情况定制自己需要的功能。

https://github.com/sofish/pen

wordpress-配置cdn加速

闲鱼站长,推荐用 Cloudflare CDN加速,因为有免费加速套餐。

方法:

只需 网站默认的  dns 服务器 改成 cloudflare  的dns服务器就行了。

注意事项:

在控制面板的 Crypto 的加密选项中,需要将 ssl 的加密模式,从 flexible 改成 full。因为我的网站自身就是只能通过https访问了。

full的含义是,从浏览器到cdn,及cdn到网站主机都是ssl加密的,如果这个地方不修改的话。那么浏览器访问网站时就会一直 redirect,redirect,redirect,最终报错显示:重定向太多。这个时候我们用 pagespeed 测速一下就会报错:Lighthouse returned error: RPC::SERVER_ERROR: Client could not parse server reply; initialization error is 。。。

优化:

等cdn能够运行,网站可以正常访问时,就可以cloudflare控制面板中的speed 选项和 cache选项中进行配置和优化。

wordpress-从http迁移到https

一、获取并配置 https 证书

1、密码和证书-https(ssl/tls)之证书的概述及获取和网站部署 ,使网站能够通过https访问。

2、配置服务器,将网站从 http 跳转到 https。

### nginx 服务器 http 跳转 https 的配置如下
server {
listen     80;
server_name  www.huaijiujia.com;
return 301 https://www.huaijiujia.com$request_uri;
  }

二、编辑 wp-config.php 文件

# 添加下面这句话,使php网站 从 http 强制跳转到 https
define('FORCE_SSL_ADMIN', true);

三、其他操作

If that worked fine, now it’s time to do the last few steps to complete the transfer to HTTPS:

  • Update your sitemap — Ideally, your SEO plugin does this automatically. However, it doesn’t always work that way. With Yoast SEO you might have to switch off the plugin once for it to update the sitemap. Don’t forget to include it in your robots.txt file and update all other hardcoded links you might have there.
  • Add site to your webmaster tools — Go to every webmaster tool you are using and add the HTTPS version of your site as a new property. While you are there, upload the new sitemap. You might also consider doing a fetch and crawl and submit any disavow files that are already active for the old version of your site.
  • Update your CDN — If you are using a content delivery network (one of the ways to speed up your site), you also need to switch it to SSL. Many of them have that feature built in and your CDN should have documentation on this. Otherwise, ask their support to help you.
  • Make the switch in your analytics — If your analytics need a default URL, make sure to upgrade it with the new prefix. For Google Analytics, you find the option under Admin > Property Settings > Default URL. Also, note down when you made the switch to HTTPS to understand traffic changes.
  • Preserve social share counts — If you show social share counters on your site, you might have to make some changes in order to keep them up to date. Check this guide for details. Don’t forget to update the links to your site in your social profiles! And do the same in your email templates.

参考自:https://websitesetup.org/http-to-https-wordpress/#comment-131467

wordpress-网站迁移与本地主机测试

将网站定期备份到本地 ,方便本地调试 与 文件备份。 

一、网站备份迁移流程:

1、用mysql 客户端 备份数据库,导出sql

2、删除网站自动备份文件,将网站压缩打包,从服务器下载网站备份。

3、因为本地环境是Apache + php ,网站 环境是 nginx +php,所以需要迁移。

(1)开启本地mysql,导入网站 sql 数据,数据库名和原网站相同。

(2)配置本地虚拟主机,并将网站文件存放至虚拟主机目录。

(3)调整网站环境,解决其他迁移问题。


二、配置虚拟主机

mac os x已自带了apahce,so 我们不需要单独安装apache,只需修改其中配置即可。

1、修改apache主配置文件

sudo vim /etc/apache2/httpd.conf

搜索vhost关键字,将以下两行代码前的#删除

#LoadModule vhost_alias_module libexec/apache2/mod_vhost_alias.so
  
#Include /private/etc/apache2/extra/httpd-vhosts.conf

搜索php5关键字,将以下两行代码前的#删除

#LoadModule rewrite_module libexec/apache2/mod_rewrite.so

#LoadModule php5_module libexec/apache2/libphp5.so

wq保存退出,第一步完成。

2、修改虚拟主机配置文件

sudo vim /etc/apache2/extra/httpd-vhost.conf

将以下代码贴进文件尾行,并按照注释配置相关参数

<VirtualHost *:80>
    ServerAdmin [email protected]  //主机邮箱地址
    DocumentRoot "/usr/docs/dummy-host2.example.com"  //站点根目录
    ServerName dummy-host2.example.com  //站点虚拟域名
    ErrorLog "/private/var/log/apache2/dummy-host2.example.com-error_log"  //错误日志输出
    CustomLog "/private/var/log/apache2/dummy-host2.example.com-access_log" common
    <Directory "/usr/docs/dummy-host2.example.com"> //站点根目录   文件权限相关
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Require all granted
    </Directory>
</VirtualHost>

将注释中的配置项改好之后,wq保存退出。

3、修改host配置

sudo vim /etc/hosts

在文件末尾加上一行

127.0.0.1       dummy-host2.example.com  //刚配好的虚拟站点目录

保存退出。

4、将网站文件存放至虚拟主机目录,并重启服务器

sudo apachectl restart

三、调整迁移环境解决迁移问题

1、数据库密码匹配问题

为了以后的方便测试统一,将本地数据库密码与网站统一。

#### 输入密码,进入 mysql 数据库
mysql -u root -p

### 修改数据库密码
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpass');

2、wordpress 中的 wp-config.php问题

(1)Apache 只能 解析 127.0.0.1  而 Nginx 可以解析 127.0.0.1 和 localhost  ,一开始这个地方填了 localhsot,导致 Apache 无法解析。

/** MySQL hostname  正确填法如下 **/

define('DB_HOST', '127.0.0.1');

(2)开启 debug 输出模式,方便查找 错误

define('WP_DEBUG', true);

(3)服务器内部错误,debug输出下发现文件夹权限问题,无法写入缓存

### 修改网站文件的权限,对指定 文件夹 文件 读写 全开放
sudo chmod -R 777 文件夹  (递归调用,使子文件 文件夹也是这个权限) 

### 对指定 文件夹 ,设置 文件 文件夹 用户组 和用户 ;就是文件所有者
sudo  chown  –R  apache:apache  文件夹  (递归调用,使子文件 文件夹也是这个权限) 

### 最后 设置好 文件权限
sudo  chmod   –R  755 文件夹  (递归调用,使子文件 文件夹也是这个权限) 
### 检查效果效果 ,可以查看文件 权限 用户组
ls  –l   文件夹 

### 移植成功后,别忘记 关闭 debug 模式:
define('WP_DEBUG', false);

3、url路径请求问题

当完成上面的操作时,我们发现 浏览器 可以访问 网站首页了,但是无法访问网站的其他子页面。都是显示  404  错误。经过查找,是路径 重写问题。

以前是nginx 服务器 现在改为 Apache ,所以 在  Permalink Settings 中,需要重新再 保存一下即可。

这样子:网站根目录下的   .htaccess 文件会添加 路径重写模块,开启路径重写功能。

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

建议删除 以下原网站的 配置文件,网站运行时 会根据新服务器环境  提示重新配置。
wordfence-waf.php 【插件生成的安全模块】
.htaccess 文件 【Apache 服务器下的 网站配置文件】
.user.ini 文件 【不清楚 之前哪里来的,反正也是在里面 只调用了 wordfence-waf.php 文件】

nginx.conf 【这个是nginx 服务器下的 网站配置文件,我这边是一个 缓存插件 自动生成的】

总结参考:

解决wordpress能打开(无404),但帖子无法打开的办法是:
在固定链接本身设置为 /%postname%/,即文章名的前提下:

1、确保apache的mod_rewrite是开启了。
即httpd.conf中,取消注释,已变成:

LoadModule rewrite_module libexec/apache2/mod_rewrite.so

2、确保有权限可以重写url,即httpd.conf中的<Directory />的AllowOverride从None变成了All:

<Directory /> 
Options FollowSymLinks 
AllowOverride All 
Order deny,allow 
Deny from all 
</Directory>

备份网站是虚拟主机配置,重写权限应该是下面的 虚拟主机 配置目录的AllowOverride All

<VirtualHost *:80>
        ServerAdmin [email protected]
        DocumentRoot "/Users/cool/Sites/www.yyyyy.com"
        ServerName www.yyyyy.com
        ErrorLog "/private/var/log/apache2/testLocalSite-error_log"
        CustomLog "/private/var/log/apache2/testLocalSite-access_log" common

        <Directory "/Users/cool/Sites/www.yyyyy.com">
            AllowOverride All
            Require all granted
        </Directory>
</VirtualHost>

 

四、网站域名更改

UPDATE wp_options SET option_value = replace( option_value, 'http://www.aliyun.com', 'http://www.bieryun.com' ) WHERE option_name = 'home' OR option_name = 'siteurl';
UPDATE wp_posts SET post_content = replace( post_content, 'http://www.aliyun.com', 'http://www.bieryun.com' ) ;
UPDATE wp_posts SET guid = replace( guid, 'http://www.old.com', 'http://www.new.com' ) ;

### old代表旧域名、new代表新域名,将上面的执行语句修改为自己的,然后点击执行即可!

 

 


参考:

https://www.jianshu.com/p/d09bdabbe065

 

wordpress-优化php-fpm和mysql

个人小站,用VPS 搭建了  wordpress,因为系统配置低,所以需要优化一下。

一、优化 php-fpm

#用于查找配置文件
 find / -name php.ini
#结果  /etc/php.ini
ls /etc
#发现  /etc/php-fpm.conf  里面 调用了 /etc/php-fpm.d  这个是文件夹
# 进入   cd /etc/php-fpm.d
修改  pm.max_children 等参数

php-fpm进程设置多少合适,设成动态还是静态?

lnmp一键安装包》中会根据你服务器内存调整php-fpm进程数。

下面是摘自Google讨论话题:《 PHP-FPM on highload tips 》如果你的高负载网站使用PHP-FPM管理FastCGI,也许下面这些技巧对你有用

1、系统上优化


1. Increase Linux “max open files”, using the following command (must be root):

Linux下增加文件打开数,命令如下:

cat >> /etc/security/limits.conf <<EOF
* soft nproc 65535
* hard nproc 65535
* soft nofile 65535
* hard nofile 65535
EOF

可以用 ulimit -n 命令查看。

2. Using SOCKET PHP FastCGI, and put into /dev/shm on Linux;

socket连接FastCGI,/dev/shm是内存文件系统,socket放在内存中肯定会快些。

nginx 下的配置
&nbsp;location ~ \.php$ {
   #fastcgi_pass 127.0.0.1:9000;
    fastcgi_pass unix:/dev/shm/php-fcgi.sock;
    fastcgi_index index.php;
    include fastcgi.conf;
}


systemctl restart nginx [这里可能会报错 unknown directive "fastcgi_pass" 其实是因为配置包含的空格中有一些 dirty EOL(end of line) characters,重新删除添加即可]

##################################### 

修改php-fpm.conf
;listen = 127.0.0.1:9000
listen = /dev/shm/php-fcgi.sock

# 执行下面这句话,会自动生成一个 /dev/shm/php-fcgi.sock 但是文件权限不对
systemctl restart php-fpm # 所以我又添加了权限 chmod 777 /dev/shm/php-fcgi.sock


# 原因是一开始忘记添加了下面两句话,导致生成的 php-fcgi.sock 是root所有,存在权限问题
listen.owner = apache # 这里要设置网站所有者,目标权限统一
listen.group = apache # 这里要设置网站所有者,目标权限统一 
# 但是又出问题了,于sock 文件是 nginx 和 php-fpm共享的,所以nginx和php-fpm的进程需要设置成同一个用户,权限统一

##################################### 
ps aux|grep nginx     # 发现 是 nginx 用户所有
ps aux|grep php-fpm   # 发现 是 apache 用户所有

nginx的用户名在/etc/nginx/nginx.conf配置文件中,有一个user参数,查看对应的就可以。
后来浏览器访问时,发现页面加载不全,net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK)
百度后知道,nginx目录下fastcgi_temp属于nginx用户和用户组,还需要修改成 apache
chown  -R  apache:apache /etc/nginx/fastcgi_params

查看 php-fpm 配置文件
#vi /etc/php-fpm.d/www.conf
 
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
; RPM: apache Choosed to be able to access some dir as httpd
;user = nobody
user=apache
; RPM: Keep a group allowed to write in log dir.
;group = nobody
group=apache

# 后来发现 nginx 日志中:open() "/var/cache/nginx/fastcgi_temp/3/00/0000000003" failed (13: Permission denied) while reading
# 于是我 rm -rf /var/cache/nginx/  然后发现重启 nginx 报错,mkdir() "/var/cache/nginx/client_temp" failed (2: No such file or directory)
# 于是我 mkdir /var/cache/nginx

mkdir /var/cache/nginx

 

Unix域Socket因为不走网络,的确可以提高Nginx和php-fpm通信的性能,但在高并发时会不稳定。
Nginx会频繁报错:
     connect() to unix:/dev/shm/php-fcgi.sock failed (11: Resource temporarily unavailable) while connecting to upstream

可以通过下面两种方式提高稳定性:
1)调高nginx和php-fpm中的backlog
     配置方法为:在nginx配置文件中这个域名的server下,在listen 80后面添加default backlog=1024。
     同时配置php-fpm.conf中的listen.backlog为1024,默认为128。
2)增加sock文件和php-fpm实例数
     再新建一个sock文件,在Nginx中通过upstream模块将请求负载均衡到两个sock文件背后的两套php-fpm实例上。

 

3. Compile PHP’s modules as less as possible, the simple the best (fast);

尽量少安装PHP模块,最简单是最好(快)的

妈蛋的 一个 php-fpm 占了80M
# 查看装了哪些 php 模块 ;卸载只要  yum remove 模块名
rpm -qa | grep php

# 下面是 必须要装的模块
php71w-common-7.1.22-1.w7.x86_64 【这个才是真正的主模块】
php71w-cli-7.1.22-1.w7.x86_64
php71w-mysql-7.1.22-1.w7.x86_64
php71w-pdo-7.1.22-1.w7.x86_64
php71w-fpm-7.1.22-1.w7.x86_64

# 下面是没有必要装的
mod_php71w-7.1.22-1.w7.x86_64  【这个模块应该是独立于其他模块的,可以删除,因为卸载7.1版本时,这个模块根本就没有删除】
php71w-xml-7.1.22-1.w7.x86_64
php71w-soap-7.1.22-1.w7.x86_64
php71w-mcrypt-7.1.22-1.w7.x86_64
php71w-xmlrpc-7.1.22-1.w7.x86_64
php71w-gd-7.1.22-1.w7.x86_64  // 作用是 png 转成 jpg

4. Using PHP code accelerator, e.g eAccelerator, XCache. And set “cache_dir” to /dev/shm on Linux.

使用php代码加速器,有那些PHP Opcode缓存插件?
Optimizer+(Optimizer+于2013年3月中旬改名为Opcache,PHP 5.5集成Opcache,其他的会不会消失?)、eAccelerator、xcache、APC …,例如 eAccelerator, XCache.在Linux平台上可以把`cache_dir`指向 /dev/shm

Opcache 缓存默认就存放在内存中,所以不需要指定目录了。

yum install php-opcache
# 相关配置
# vim /etc/php.d/10-opcache.ini

# 安装完后,直接用wordpress 的 W3 Total Cache 插件设置缓存 到这里就行了。

===============================
可以安装 redis 服务,启动服务端后,需要 php的 驱动
yum list | grep php72w*  ## 从网上查找所有的 php 插件
yum install php72w-pecl-redis  
## PECL is a repository for PHP Extensions, providing a directory of all known extensions and hosting facilities for downloading and development of PHP extensions.
安装完 redis 驱动后 ,直接用wordpress 的 W3 Total Cache 插件设置缓存 到这里就行了

2、php-fpm 配置文件优化


1. Increas PHP FastCGI child number to 100 and even more. Sometime, 200 is OK! ( On 4GB memory server);

把你的PHP FastCGI子进程数调到100或以上,在4G内存的服务器上200就可以(建议压力测试来得出自己服务器合理的值)其实就是 php-fpm 进程数
配置文件/etc/php-fpm.conf --> /etc/php-fpm.d/www.conf
这个配置文件的里面的池名[www] 就对应网站的域名 ,两者互相对应。这个配置文件即可以用来设置 php-fpm 运行时的用户名和用户组,也可以生成 sock文件,并规定用户名和用户组。

; Start a new pool named 'www'.
[www]

; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
; RPM: apache Choosed to be able to access some dir as httpd
user = apache
; RPM: Keep a group allowed to write in log dir.
group = apache

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
;                            a specific port;
;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses
;                            (IPv6 and IPv4-mapped) on a specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
;listen = 127.0.0.1:9000
listen = /dev/shm/php-fcgi.sock

; 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 = nobody
;listen.group = nobody
;listen.mode = 0660
listen.owner = apache
listen.group = apache

# 查看php-fpm的进程个数
ps -fe |grep "php-fpm"|grep "pool"|wc -l

# 查看每个php-fpm占用的内存大小
ps -ylC php-fpm --sort:rss

# 配置php-fpm参数
pm = dynamic #动态适合小内存机器,灵活分配进程,省内存。静态适用于大内存机器,动态创建回收进程对服务器资源也是一种消耗。
#如何控制子进程,选项有static和dynamic。如果选择static,则由pm.max_children指定固定的子进程数。如果选择dynamic,则由下开参数决定:

pm.max_children #子进程最大数
pm.start_servers #启动时的进程数
pm.min_spare_servers #保证空闲进程数最小值,如果空闲进程小于此值,则创建新的子进程
pm.max_spare_servers #保证空闲进程数最大值,如果空闲进程大于此值,此进行清理

###  我的 1G 主机,测试使用发现  一个 php-fpm 占了80M,所以进程配置了最多10个

2.其他参数

rlimit_files = 51200
Increase PHP-FPM open file description rlimit:增加 PHP-FPM 打开文件描述符的限制。

pm.max_requests = 10240;
每个请求完成后php-cgi会回收内存,但是不会释放给操作系统,这样就会导致大量内存被php-cgi占用。官方的解决办法是降低PHP_FCGI_MAX_REQUESTS的值,如果用的是php-fpm,对应的php-fpm.conf中的就是max_requests,该值的意思是发送多少个请求后会重启该线程,我们需要适当降低这个值,用以让php-fpm自动的释放内存,不是大部分网上说的51200等等。

request_terminate_timeout = 30;
最大执行时间, 在php.ini中也可以进行配置(max_execution_time)默认值为 0 秒,也就是说,PHP 脚本会一直执行下去。这样,当所有的 php-cgi 进程都卡在 file_get_contents() 函数时,这台 Nginx+PHP 的 WebServer 已经无法再处理新的 PHP 请求了,Nginx 将给用户返回“502 Bad Gateway”。可以使用 request_terminate_timeout = 30s,但是如果发生 file_get_contents() 获取网页内容较慢的情况,这就意味着 150 个 php-cgi 进程,每秒钟只能处理 5 个请求,WebServer 同样很难避免“502 Bad Gateway”。php-cgi进程数不够用、php执行时间长、或者是php-cgi进程死掉,都会出现502错误。

用strace跟踪 超时进程:
利用nohup将strace转为后台执行,直到attach上的php-fpm进程死掉为止:
nohup strace -T -p 13167 > 13167-strace.log &

参数说明:

-c 统计每一系统调用的所执行的时间,次数和出错的次数等.
-d 输出strace关于标准错误的调试信息.
-f 跟踪由fork调用所产生的子进程.
-o filename,则所有进程的跟踪结果输出到相应的filename
-F 尝试跟踪vfork调用.在-f时,vfork不被跟踪.
-h 输出简要的帮助信息.
-i 输出系统调用的入口指针.
-q 禁止输出关于脱离的消息.
-r 打印出相对时间关于,,每一个系统调用.
-t 在输出中的每一行前加上时间信息.
-tt 在输出中的每一行前加上时间信息,微秒级.
-ttt 微秒级输出,以秒了表示时间.
-T 显示每一调用所耗的时间.
-v 输出所有的系统调用.一些调用关于环境变量,状态,输入输出等调用由于使用频繁,默认不输出.
-V 输出strace的版本信息.
-x 以十六进制形式输出非标准字符串
-xx 所有字符串以十六进制形式输出.
-a column
设置返回值的输出位置.默认为40.
-e execve 只记录 execve 这类系统调用
-p 主进程号

request_slowlog_timeout = 2; 配置输出php-fpm慢日志,阀值为2秒:
slowlog =/tmp/www.slow.log; 慢日志路径,可以自己定路径。
利用sort/uniq命令分析汇总php-fpm慢日志:

[root@b28-12 log]# grep -v "^$" www.log.slow.tmp | cut -d " " -f 3,2 | sort | uniq -c | sort -k1,1nr | head -n 50

   5181 run() /www/test.net/framework/web/filters/CFilter.php:41

   5156 filter() /www/test.net/framework/web/filters/CFilterChain.php:131

   2670 = /www/test.net/index.php

   2636 run() /www/test.net/application/controllers/survey/index.php:665

   2630 action() /www/test.net/application/controllers/survey/index.php:18

   2625 run() /www/test.net/framework/web/actions/CAction.php:75

   2605 runWithParams() /www/test.net/framework/web/CController.php:309

   2604 runAction() /www/test.net/framework/web/filters/CFilterChain.php:134

   2538 run() /www/test.net/framework/web/CController.php:292

   2484 runActionWithFilters() /www/test.net/framework/web/CController.php:266

   2251 run() /www/test.net/framework/web/CWebApplication.php:276

   1799 translate() /www/test.net/application/libraries/Limesurvey_lang.php:118

   1786 load_tables() /www/test.net/application/third_party/php-gettext/gettext.php:254

   1447 runController() /www/test.net/framework/web/CWebApplication.php:135

参数解释:
sort:  对单词进行排序
uniq -c:  显示唯一的行,并在每行行首加上本行在文件中出现的次数
sort -k1,1nr:  按照第一个字段,数值排序,且为逆序
head -10:  取前10行数据

3、PHP性能监控


常用的方法就是开启xdebug的性能监控功能,将xdebug输出结果通过WinCacheGrind软件分析。
xdebug的安装和配合IDE调试的方法参见:Vim+XDebug调试PHP

php.ini中配置的这几项是输出性能信息的:

xdebug.auto_trace = on

xdebug.auto_profile = on
xdebug.collect_params = on
xdebug.collect_return = on
xdebug.profiler_enable = on
xdebug.trace_output_dir = "/tmp"
xdebug.profiler_output_dir ="/tmp"

这样XDebug会输出所有执行php函数的性能数据,但产生的文件也会比较大。可以关闭一些选项如collect_params、collect_return,来减少输出的数据量。或者关闭自动输出,通过在想要监控的函数首尾调用xdebug函数来监控指定的函数。输出的文件名类似cachegrind.out.1277560600和trace.3495983249.txt,可以拿到Windows平台下用WinCacheGrind进行图形化分析。

在线监测:

# nginx 配置
location ~ ^/status$ {
    include fastcgi_params;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
}

# php-fpm配置
pm.status_path = /status

###############################
这样的话通过http://域名/status就可以看到当前的php情况

  下面介绍每个参数的作用:
  pool:php-fpm池的名称,一般都是应该是www
  process manage:进程的管理方法,php-fpm支持三种管理方法,分别是static,dynamic和ondemand,一般情况下都是dynamic
  start time:php-fpm启动时候的时间,不管是restart或者reload都会更新这里的时间
  start since:php-fpm自启动起来经过的时间,默认为秒
  accepted conn:当前接收的连接数
  listen queue:在队列中等待连接的请求个数,如果这个数字为非0,那么最好增加进程的fpm个数
  max listen queue:从fpm启动以来,在队列中等待连接请求的最大值
  listen queue len:等待连接的套接字队列大小
  idle processes:空闲的进程个数
  active processes:活动的进程个数
  total processes:总共的进程个数
  max active processes:从fpm启动以来,活动进程的最大个数,如果这个值小于当前的max_children,可以调小此值
  max children reached:当pm尝试启动更多的进程,却因为max_children的限制,没有启动更多进程的次数。如果这个值非0,那么可以适当增加fpm的进程数
  slow requests:慢请求的次数,一般如果这个值未非0,那么可能会有慢的php进程,一般一个不好的mysql查询是最大的祸首。

二、优化mysql

my.cnf  【经过使用,目前mysql5.7版本,使用默认配置,内存占用稳定在20%左右,我也懒得优化了】

MySQL 5.6版本适合在1GB内存VPS上的my.cnf配置文件(点击这里下载文件):

[client]  
port = 3306  
socket = /tmp/mysql.sock  
  
[mysqld]  
port = 3306  
socket = /tmp/mysql.sock  
  
basedir = /usr/local/mysql  
datadir = /data/mysql  
pid-file = /data/mysql/mysql.pid  
user = mysql  
bind-address = 0.0.0.0  
server-id = 1 #表示是本机的序号为1,一般来讲就是master的意思  
  
skip-name-resolve  
# 禁止MySQL对外部连接进行DNS解析,使用这一选项可以消除MySQL进行DNS解析的时间。但需要注意,如果开启该选项,  
# 则所有远程主机连接授权都要使用IP地址方式,否则MySQL将无法正常处理连接请求  
  
#skip-networking  
  
back_log = 600  
# MySQL能有的连接数量。当主要MySQL线程在一个很短时间内得到非常多的连接请求,这就起作用,  
# 然后主线程花些时间(尽管很短)检查连接并且启动一个新线程。back_log值指出在MySQL暂时停止回答新请求之前的短时间内多少个请求可以被存在堆栈中。  
# 如果期望在一个短时间内有很多连接,你需要增加它。也就是说,如果MySQL的连接数据达到max_connections时,新来的请求将会被存在堆栈中,  
# 以等待某一连接释放资源,该堆栈的数量即back_log,如果等待连接的数量超过back_log,将不被授予连接资源。  
# 另外,这值(back_log)限于您的操作系统对到来的TCP/IP连接的侦听队列的大小。  
# 你的操作系统在这个队列大小上有它自己的限制(可以检查你的OS文档找出这个变量的最大值),试图设定back_log高于你的操作系统的限制将是无效的。  
  
max_connections = 1000  
# MySQL的最大连接数,如果服务器的并发连接请求量比较大,建议调高此值,以增加并行连接数量,当然这建立在机器能支撑的情况下,因为如果连接数越多,介于MySQL会为每个连接提供连接缓冲区,就会开销越多的内存,所以要适当调整该值,不能盲目提高设值。可以过'conn%'通配符查看当前状态的连接数量,以定夺该值的大小。  
  
max_connect_errors = 6000  
# 对于同一主机,如果有超出该参数值个数的中断错误连接,则该主机将被禁止连接。如需对该主机进行解禁,执行:FLUSH HOST。  
  
open_files_limit = 65535  
# MySQL打开的文件描述符限制,默认最小1024;当open_files_limit没有被配置的时候,比较max_connections*5和ulimit -n的值,哪个大用哪个,  
# 当open_file_limit被配置的时候,比较open_files_limit和max_connections*5的值,哪个大用哪个。  
  
table_open_cache = 128  
# MySQL每打开一个表,都会读入一些数据到table_open_cache缓存中,当MySQL在这个缓存中找不到相应信息时,才会去磁盘上读取。默认值64  
# 假定系统有200个并发连接,则需将此参数设置为200*N(N为每个连接所需的文件描述符数目);  
# 当把table_open_cache设置为很大时,如果系统处理不了那么多文件描述符,那么就会出现客户端失效,连接不上  
  
max_allowed_packet = 4M  
# 接受的数据包大小;增加该变量的值十分安全,这是因为仅当需要时才会分配额外内存。例如,仅当你发出长查询或MySQLd必须返回大的结果行时MySQLd才会分配更多内存。  
# 该变量之所以取较小默认值是一种预防措施,以捕获客户端和服务器之间的错误信息包,并确保不会因偶然使用大的信息包而导致内存溢出。  
  
binlog_cache_size = 1M  
# 一个事务,在没有提交的时候,产生的日志,记录到Cache中;等到事务提交需要提交的时候,则把日志持久化到磁盘。默认binlog_cache_size大小32K  
  
max_heap_table_size = 8M  
# 定义了用户可以创建的内存表(memory table)的大小。这个值用来计算内存表的最大行数值。这个变量支持动态改变  
  
tmp_table_size = 16M  
# MySQL的heap(堆积)表缓冲大小。所有联合在一个DML指令内完成,并且大多数联合甚至可以不用临时表即可以完成。  
# 大多数临时表是基于内存的(HEAP)表。具有大的记录长度的临时表 (所有列的长度的和)或包含BLOB列的表存储在硬盘上。  
# 如果某个内部heap(堆积)表大小超过tmp_table_size,MySQL可以根据需要自动将内存中的heap表改为基于硬盘的MyISAM表。还可以通过设置tmp_table_size选项来增加临时表的大小。也就是说,如果调高该值,MySQL同时将增加heap表的大小,可达到提高联接查询速度的效果  
  
read_buffer_size = 2M  
# MySQL读入缓冲区大小。对表进行顺序扫描的请求将分配一个读入缓冲区,MySQL会为它分配一段内存缓冲区。read_buffer_size变量控制这一缓冲区的大小。  
# 如果对表的顺序扫描请求非常频繁,并且你认为频繁扫描进行得太慢,可以通过增加该变量值以及内存缓冲区大小提高其性能  
  
read_rnd_buffer_size = 8M  
# MySQL的随机读缓冲区大小。当按任意顺序读取行时(例如,按照排序顺序),将分配一个随机读缓存区。进行排序查询时,  
# MySQL会首先扫描一遍该缓冲,以避免磁盘搜索,提高查询速度,如果需要排序大量数据,可适当调高该值。但MySQL会为每个客户连接发放该缓冲空间,所以应尽量适当设置该值,以避免内存开销过大  
  
sort_buffer_size = 8M  
# MySQL执行排序使用的缓冲大小。如果想要增加ORDER BY的速度,首先看是否可以让MySQL使用索引而不是额外的排序阶段。  
# 如果不能,可以尝试增加sort_buffer_size变量的大小  
  
join_buffer_size = 8M  
# 联合查询操作所能使用的缓冲区大小,和sort_buffer_size一样,该参数对应的分配内存也是每连接独享  
  
thread_cache_size = 8  
# 这个值(默认8)表示可以重新利用保存在缓存中线程的数量,当断开连接时如果缓存中还有空间,那么客户端的线程将被放到缓存中,  
# 如果线程重新被请求,那么请求将从缓存中读取,如果缓存中是空的或者是新的请求,那么这个线程将被重新创建,如果有很多新的线程,  
# 增加这个值可以改善系统性能.通过比较Connections和Threads_created状态的变量,可以看到这个变量的作用。(–>表示要调整的值)  
# 根据物理内存设置规则如下:  
# 1G  —> 8  
# 2G  —> 16  
# 3G  —> 32  
# 大于3G  —> 64  
  
query_cache_size = 8M  
#MySQL的查询缓冲大小(从4.0.1开始,MySQL提供了查询缓冲机制)使用查询缓冲,MySQL将SELECT语句和查询结果存放在缓冲区中,  
# 今后对于同样的SELECT语句(区分大小写),将直接从缓冲区中读取结果。根据MySQL用户手册,使用查询缓冲最多可以达到238%的效率。  
# 通过检查状态值'Qcache_%',可以知道query_cache_size设置是否合理:如果Qcache_lowmem_prunes的值非常大,则表明经常出现缓冲不够的情况,  
# 如果Qcache_hits的值也非常大,则表明查询缓冲使用非常频繁,此时需要增加缓冲大小;如果Qcache_hits的值不大,则表明你的查询重复率很低,  
# 这种情况下使用查询缓冲反而会影响效率,那么可以考虑不用查询缓冲。此外,在SELECT语句中加入SQL_NO_CACHE可以明确表示不使用查询缓冲  
  
query_cache_limit = 2M  
#指定单个查询能够使用的缓冲区大小,默认1M  
  
key_buffer_size = 4M  
#指定用于索引的缓冲区大小,增加它可得到更好处理的索引(对所有读和多重写),到你能负担得起那样多。如果你使它太大,  
# 系统将开始换页并且真的变慢了。对于内存在4GB左右的服务器该参数可设置为384M或512M。通过检查状态值Key_read_requests和Key_reads,  
# 可以知道key_buffer_size设置是否合理。比例key_reads/key_read_requests应该尽可能的低,  
# 至少是1:100,1:1000更好(上述状态值可以使用SHOW STATUS LIKE 'key_read%'获得)。注意:该参数值设置的过大反而会是服务器整体效率降低  
  
ft_min_word_len = 4  
# 分词词汇最小长度,默认4  
  
transaction_isolation = REPEATABLE-READ  
# MySQL支持4种事务隔离级别,他们分别是:  
# READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.  
# 如没有指定,MySQL默认采用的是REPEATABLE-READ,ORACLE默认的是READ-COMMITTED  
  
log_bin = mysql-bin  
binlog_format = mixed  
expire_logs_days = 30 #超过30天的binlog删除  
  
log_error = /data/mysql/mysql-error.log #错误日志路径  
slow_query_log = 1  
long_query_time = 1 #慢查询时间 超过1秒则为慢查询  
slow_query_log_file = /data/mysql/mysql-slow.log  
  
performance_schema = 0  
explicit_defaults_for_timestamp  
  
#lower_case_table_names = 1 #不区分大小写  
  
skip-external-locking #MySQL选项以避免外部锁定。该选项默认开启  
  
default-storage-engine = InnoDB #默认存储引擎  
  
innodb_file_per_table = 1  
# InnoDB为独立表空间模式,每个数据库的每个表都会生成一个数据空间  
# 独立表空间优点:  
# 1.每个表都有自已独立的表空间。  
# 2.每个表的数据和索引都会存在自已的表空间中。  
# 3.可以实现单表在不同的数据库中移动。  
# 4.空间可以回收(除drop table操作处,表空不能自已回收)  
# 缺点:  
# 单表增加过大,如超过100G  
# 结论:  
# 共享表空间在Insert操作上少有优势。其它都没独立表空间表现好。当启用独立表空间时,请合理调整:innodb_open_files  
  
innodb_open_files = 500  
# 限制Innodb能打开的表的数据,如果库里的表特别多的情况,请增加这个。这个值默认是300  
  
innodb_buffer_pool_size = 64M  
# InnoDB使用一个缓冲池来保存索引和原始数据, 不像MyISAM.  
# 这里你设置越大,你在存取表里面数据时所需要的磁盘I/O越少.  
# 在一个独立使用的数据库服务器上,你可以设置这个变量到服务器物理内存大小的80%  
# 不要设置过大,否则,由于物理内存的竞争可能导致操作系统的换页颠簸.  
# 注意在32位系统上你每个进程可能被限制在 2-3.5G 用户层面内存限制,  
# 所以不要设置的太高.  
  
innodb_write_io_threads = 4  
innodb_read_io_threads = 4  
# innodb使用后台线程处理数据页上的读写 I/O(输入输出)请求,根据你的 CPU 核数来更改,默认是4  
# 注:这两个参数不支持动态改变,需要把该参数加入到my.cnf里,修改完后重启MySQL服务,允许值的范围从 1-64  
  
innodb_thread_concurrency = 0  
# 默认设置为 0,表示不限制并发数,这里推荐设置为0,更好去发挥CPU多核处理能力,提高并发量  
  
innodb_purge_threads = 1  
# InnoDB中的清除操作是一类定期回收无用数据的操作。在之前的几个版本中,清除操作是主线程的一部分,这意味着运行时它可能会堵塞其它的数据库操作。  
# 从MySQL5.5.X版本开始,该操作运行于独立的线程中,并支持更多的并发数。用户可通过设置innodb_purge_threads配置参数来选择清除操作是否使用单  
# 独线程,默认情况下参数设置为0(不使用单独线程),设置为 1 时表示使用单独的清除线程。建议为1  
  
innodb_flush_log_at_trx_commit = 2  
# 0:如果innodb_flush_log_at_trx_commit的值为0,log buffer每秒就会被刷写日志文件到磁盘,提交事务的时候不做任何操作(执行是由mysql的master thread线程来执行的。  
# 主线程中每秒会将重做日志缓冲写入磁盘的重做日志文件(REDO LOG)中。不论事务是否已经提交)默认的日志文件是ib_logfile0,ib_logfile1  
# 1:当设为默认值1的时候,每次提交事务的时候,都会将log buffer刷写到日志。  
# 2:如果设为2,每次提交事务都会写日志,但并不会执行刷的操作。每秒定时会刷到日志文件。要注意的是,并不能保证100%每秒一定都会刷到磁盘,这要取决于进程的调度。  
# 每次事务提交的时候将数据写入事务日志,而这里的写入仅是调用了文件系统的写入操作,而文件系统是有 缓存的,所以这个写入并不能保证数据已经写入到物理磁盘  
# 默认值1是为了保证完整的ACID。当然,你可以将这个配置项设为1以外的值来换取更高的性能,但是在系统崩溃的时候,你将会丢失1秒的数据。  
# 设为0的话,mysqld进程崩溃的时候,就会丢失最后1秒的事务。设为2,只有在操作系统崩溃或者断电的时候才会丢失最后1秒的数据。InnoDB在做恢复的时候会忽略这个值。  
# 总结  
# 设为1当然是最安全的,但性能页是最差的(相对其他两个参数而言,但不是不能接受)。如果对数据一致性和完整性要求不高,完全可以设为2,如果只最求性能,例如高并发写的日志服务器,设为0来获得更高性能  
  
innodb_log_buffer_size = 2M  
# 此参数确定些日志文件所用的内存大小,以M为单位。缓冲区更大能提高性能,但意外的故障将会丢失数据。MySQL开发人员建议设置为1-8M之间  
  
innodb_log_file_size = 32M  
# 此参数确定数据日志文件的大小,更大的设置可以提高性能,但也会增加恢复故障数据库所需的时间  
  
innodb_log_files_in_group = 3  
# 为提高性能,MySQL可以以循环方式将日志文件写到多个文件。推荐设置为3  
  
innodb_max_dirty_pages_pct = 90  
# innodb主线程刷新缓存池中的数据,使脏数据比例小于90%  
  
innodb_lock_wait_timeout = 120   
# InnoDB事务在被回滚之前可以等待一个锁定的超时秒数。InnoDB在它自己的锁定表中自动检测事务死锁并且回滚事务。InnoDB用LOCK TABLES语句注意到锁定设置。默认值是50秒  
  
bulk_insert_buffer_size = 8M  
# 批量插入缓存大小, 这个参数是针对MyISAM存储引擎来说的。适用于在一次性插入100-1000+条记录时, 提高效率。默认值是8M。可以针对数据量的大小,翻倍增加。  
  
myisam_sort_buffer_size = 8M  
# MyISAM设置恢复表之时使用的缓冲区的尺寸,当在REPAIR TABLE或用CREATE INDEX创建索引或ALTER TABLE过程中排序 MyISAM索引分配的缓冲区  
  
myisam_max_sort_file_size = 10G  
# 如果临时文件会变得超过索引,不要使用快速排序索引方法来创建一个索引。注释:这个参数以字节的形式给出  
  
myisam_repair_threads = 1  
# 如果该值大于1,在Repair by sorting过程中并行创建MyISAM表索引(每个索引在自己的线程内)    
  
interactive_timeout = 28800  
# 服务器关闭交互式连接前等待活动的秒数。交互式客户端定义为在mysql_real_connect()中使用CLIENT_INTERACTIVE选项的客户端。默认值:28800秒(8小时)  
  
wait_timeout = 28800  
# 服务器关闭非交互连接之前等待活动的秒数。在线程启动时,根据全局wait_timeout值或全局interactive_timeout值初始化会话wait_timeout值,  
# 取决于客户端类型(由mysql_real_connect()的连接选项CLIENT_INTERACTIVE定义)。参数默认值:28800秒(8小时)  
# MySQL服务器所支持的最大连接数是有上限的,因为每个连接的建立都会消耗内存,因此我们希望客户端在连接到MySQL Server处理完相应的操作后,  
# 应该断开连接并释放占用的内存。如果你的MySQL Server有大量的闲置连接,他们不仅会白白消耗内存,而且如果连接一直在累加而不断开,  
# 最终肯定会达到MySQL Server的连接上限数,这会报'too many connections'的错误。对于wait_timeout的值设定,应该根据系统的运行情况来判断。  
# 在系统运行一段时间后,可以通过show processlist命令查看当前系统的连接状态,如果发现有大量的sleep状态的连接进程,则说明该参数设置的过大,  
# 可以进行适当的调整小些。要同时设置interactive_timeout和wait_timeout才会生效。  
  
[mysqldump]  
quick  
max_allowed_packet = 16M #服务器发送和接受的最大包长度  
  
[myisamchk]  
key_buffer_size = 8M  
sort_buffer_size = 8M  
read_buffer = 4M  
write_buffer = 4M

 

参考:

https://blog.csdn.net/dc_726/article/details/12340349

https://blog.csdn.net/dc_726/article/details/9336193

https://blog.linuxeye.cn/380.html

wordpress-上传文件类型限制

楼主想上传一个脚本文件到wordpress,但是 发现 由于安全限制,无法上传。

文件类型不符合安全规则。试试别的文件。

这种错误是由于WordPress中做了文件上传格式的限制,这种限制可以在WordPress中的wp-include/functions.php的get_allowed_mime_types函数中找到,函数如下:

function get_allowed_mime_types() {
static $mimes = false;
if ( !$mimes ) {
// Accepted MIME types are set here as PCRE unless provided.
$mimes = apply_filters( ‘upload_mimes’, array(
‘jpg|jpeg|jpe’ => ‘image/jpeg’,
‘gif’ => ‘image/gif’,
‘png’ => ‘image/png’,
‘bmp’ => ‘image/bmp’,
‘tif|tiff’ => ‘image/tiff’,
‘ico’ => ‘image/x-icon’,
‘asf|asx|wax|wmv|wmx’ => ‘video/asf’,
‘avi’ => ‘video/avi’,
‘divx’ => ‘video/divx’,
‘flv’ => ‘video/x-flv’,
‘mov|qt’ => ‘video/quicktime’,
‘mpeg|mpg|mpe’ => ‘video/mpeg’,
‘txt|c|cc|h’ => ‘text/plain’,
‘rtx’ => ‘text/richtext’,
‘css’ => ‘text/css’,
‘htm|html’ => ‘text/html’,
‘mp3|m4a’ => ‘audio/mpeg’,
‘mp4|m4v’ => ‘video/mp4′,
‘ra|ram’ => ‘audio/x-realaudio’,
‘wav’ => ‘audio/wav’,
‘ogg’ => ‘audio/ogg’,
‘mid|midi’ => ‘audio/midi’,
‘wma’ => ‘audio/wma’,
‘rtf’ => ‘application/rtf’,
‘js’ => ‘application/javascript’,
‘pdf’ => ‘application/pdf’,
‘doc|docx’ => ‘application/msword’,
‘pot|pps|ppt|pptx’ => ‘application/vnd.ms-powerpoint’,
‘wri’ => ‘application/vnd.ms-write’,
‘xla|xls|xlsx|xlt|xlw’ => ‘application/vnd.ms-excel’,
‘mdb’ => ‘application/vnd.ms-access’,
‘mpp’ => ‘application/vnd.ms-project’,
’swf’ => ‘application/x-shockwave-flash’,
‘class’ => ‘application/java’,
‘tar’ => ‘application/x-tar’,
‘zip’ => ‘application/zip’,
‘gz|gzip’ => ‘application/x-gzip’,
‘exe’ => ‘application/x-msdownload’,
// openoffice formats
‘odt’ => ‘application/vnd.oasis.opendocument.text’,
‘odp’ => ‘application/vnd.oasis.opendocument.presentation’,
‘ods’ => ‘application/vnd.oasis.opendocument.spreadsheet’,
‘odg’ => ‘application/vnd.oasis.opendocument.graphics’,
‘odc’ => ‘application/vnd.oasis.opendocument.chart’,
‘odb’ => ‘application/vnd.oasis.opendocument.database’,
‘odf’ => ‘application/vnd.oasis.opendocument.formula’,
) );
}
return $mimes;
}

以上传入 apply_filters函数中的Array,即使允许上传的类型列表,我们可以修改这个地方,以禁止或允许可以上传的文件类型。

例如我们想要允许rar文件上传,只需添加一行格式说明即可:

‘rar’ => ‘application/rar’,

除了直接修改这个Array外,还有另外一种方法,可以修改wp-config.php文件,这个文件在WordPress的根目录下,在其中增加一行语句:
define(‘ALLOW_UNFILTERED_UPLOADS’, true);

这条语句将去除上传的文件类型限制,一劳永逸。

转载自:https://www.cnblogs.com/kedarui/p/3627307.html

树莓派-JAVA操作GPIO

curl -s get.pi4j.com | sudo bash
  • 方式二,下载安装包来安装,下载地址为http://get.pi4j.com/download/pi4j-1.1.deb,下载完毕后执行以下命令,即可完成安装:
sudo dpkg -i pi4j-1.1.deb

安装之后,PI4J的库放在以下目录:

/opt/pi4j/lib

如果你想更新PI4J,可以执行以下命令:

sudo apt-get install pi4j

或者

pi4j --update

如果想要卸载PI4J,可以执行以下命令

sudo apt-get remove pi4j 或 pi4j --uninstall

完全卸载方式:

curl -s get.pi4j.com/uninstall | sudo bash

PI4J的官方demo

安装PI4J之后,就应该尽快入门PI4J了,而学习PI4J最好的办法就是一边看着官方demo,一边动手写代码。
如果你按照上面的方式安装PI4J,那么官方文档在以下目录:

/opt/pi4j/examples

进入该目录,执行以下命令,可编译源代码:

sudo /opt/pi4j/examples/build

编译之后,你可以随意运行某个demo,比如这里运行BlinkGpioExample,那么执行以下命令:

./run BlinkGpioExample

demo简要解析

毕竟大家都是新手,光有代码恐怕还不能困惑,所以这里就拿一个例子讲解一下代码,方便大家入门。

在讲解之前,大家除了准备树莓派,还要先自备好led灯,以及一个开关按钮(某宝上搜有很多),因为大多的官方例子里都使用到。

好了,大家先看看两个图,这两个图表示这树莓派2(树莓派3点此)上的针脚。也就是我们所说的GPIO。

图一是真实树莓派的针脚图,图一的箭头1,箭头2指向图二顶头的两个针脚。这里需要注意的是,图二两边的粗体数字,这是PI4J的针脚编号。

好了,我们开始看代码,打开/opt/pi4j/examples/ControlGpioExample.java:

/*
 * #%L
 * **********************************************************************
 * ORGANIZATION  :  Pi4J
 * PROJECT       :  Pi4J :: Java Examples
 * FILENAME      :  ControlGpioExample.java
 *
 * This file is part of the Pi4J project. More information about
 * this project can be found here:  http://www.pi4j.com/
 * **********************************************************************
 */
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;

/**
 * This example code demonstrates how to perform simple state
 * control of a GPIO pin on the Raspberry Pi.
 *
 * @author Robert Savage
 */
public class ControlGpioExample {

    public static void main(String[] args) throws InterruptedException {

        System.out.println("<--Pi4J--> GPIO Control Example ... started.");

        // create gpio controller
        final GpioController gpio = GpioFactory.getInstance();

        // provision gpio pin #01 as an output pin and turn on
        final GpioPinDigitalOutput pin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_01, "MyLED", PinState.HIGH);

        // set shutdown state for this pin
        pin.setShutdownOptions(true, PinState.LOW);

        System.out.println("--> GPIO state should be: ON");

        Thread.sleep(5000);

        // turn off gpio pin #01
        pin.low();
        System.out.println("--> GPIO state should be: OFF");

        Thread.sleep(5000);

        // toggle the current state of gpio pin #01 (should turn on)
        pin.toggle();
        System.out.println("--> GPIO state should be: ON");

        Thread.sleep(5000);

        // toggle the current state of gpio pin #01  (should turn off)
        pin.toggle();
        System.out.println("--> GPIO state should be: OFF");

        Thread.sleep(5000);

        // turn on gpio pin #01 for 1 second and then off
        System.out.println("--> GPIO state should be: ON for only 1 second");
        pin.pulse(1000, true); // set second argument to 'true' use a blocking call

        // stop all GPIO activity/threads by shutting down the GPIO controller
        // (this method will forcefully shutdown all GPIO monitoring threads and scheduled tasks)
        gpio.shutdown();

        System.out.println("Exiting ControlGpioExample");
    }
}

连接图

要查看上面代码的运行效果,需要按照如下图所示接入LED灯:

执行

连接之后,执行命令:

./run ControlGpioExample

输出

这个例子的LED输出应该是这样的:

Turn ON for 5 seconds

Turn OFF for 5 seconds

Turn ON for 5 seconds

Turn OFF for 5 seconds

Turn ON for 1 second

Turn OFF

更多的例子解析,可以直接看PI4J的官方网站,非常详细。官方网站:http://pi4j.com/index.html

开发maven环境

这里简要说一下maven开发环境。毕竟如果真要做一些好东西出来,自然少不了用maven来管理项目。

在树莓派上安装maven,参考官方文档:http://maven.apache.org/install.html

PI4J的maven配置是:

<dependency>
    <groupId>com.pi4j</groupId>
    <artifactId>pi4j-core</artifactId>
    <version>1.1</version>
</dependency>

我的树莓派学习项目github地址:https://github.com/dasheng523/pi
我会一直学习,并加入一些模块的驱动开发代码。有兴趣的同学可以加入进来一起玩转树莓派。

 

转载自:http://blog.hyesheng.com/2016-09-07-raspberry03/

树莓派-常用方法控制GPIO

常用开源工程简介

树莓派内核中已经编译自带了 gpio 的驱动,我们常通过一些第三方写好的库函数来完成具体的操作,比较常见的操作库函数有:

python GPIO

  • 开发语言——python
  • 简单介绍——树莓派官方资料中推荐且容易上手。python GPIO 是一个小型的 python 库,可以帮助用户完成 raspberry 相关 IO 口操作,但是 python GPIO 库还没有支持 SPI、I2C 或者 1-wire 等总线接口。
  • 官方网站—— https://code.google.com/p/raspberry-gpio-python/

wiringPi

  • 开发语言——C 语言
  • 简单介绍——wiringPi 适合那些具有 C 语言基础,在接触树莓派之前已经接触过单片机或者嵌入式开发的人群。wiringPi 的 API 函数和 arduino 非常相似,这也使得它广受欢迎。作者给出了大量的说明和示例代码,这些示例代码也包括 UART 设备,I2C 设备和 SPI 设备等。
  • 官方网站—— http://wiringpi.com/

BCM2835 C Library

  • 开发语言——C 语言
  • 简单介绍——BCM2835 C Library 可以理解为使用C语言实现的相关底层驱动,BCM2835 C Library 的驱动库包括 GPIO、SPI 和 UART 等,可以通过学习 BCM2835 C Library 熟悉 BCM2835 相关的寄存器操作。如果有机会开发树莓派上的 linux 驱动,或自主开发 python 或 PHP 扩展驱动,可以从 BCM2835 C Library 找到不少的“灵感”。
  • 官方网站—— http://www.airspayce.com/mikem/bcm2835/

树莓派GPIO编号方式

  1. 功能物理引脚: 从左到右,从上到下:左边基数,右边偶数:1-40
  2. BCM: 编号侧重 CPU 寄存器,根据 BCM2835 的 GPIO 寄存器编号。
  3. wpi: 编号侧重实现逻辑,把扩展 GPIO 端口从 0 开始编号,这种编号方便编程。正如下图 WiringPi 一栏。

python GPIO

先安装 python-dev,输入以下指令。

sudo apt-get install python-dev

安装 RPi.GPIO,依次输入以下指令。

例子:

# -*- coding: utf-8 -*-    
 import RPi.GPIO as GPIO    
 import time    
 # BOARD编号方式,基于插座引脚编号    
 GPIO.setmode(GPIO.BOARD)    
 # 输出模式    
 GPIO.setup(11, GPIO.OUT)    

 while True:    
     GPIO.output(11, GPIO.HIGH)    
     time.sleep(1)    
     GPIO.output(11, GPIO.LOW)    
     time.sleep(1)   

执行:

sudo python led.py

说明:

  • GPIO.setmode(GPIO.BOARD),采用插座引脚编号方式。
  • 由于采用插座引脚编号方式,此处的 11 脚相当于 BCM2835 寄存器编号方式的引脚 11。

WiringPi GPIO

说明

WiringPi 是应用于树莓派平台的 GPIO 控制库函数,WiringPi 遵守 GUN Lv3。wiringPi 使用 C 或者 C++ 开发并且可以被其他语言包转,例如 Python、ruby 或者 PHP 等。 wiringPi 包括一套 gpio 控制命令,使用 gpio 命令可以控制树莓派 GPIO 管脚。用户可以利用 gpio 命令通过 shell 脚本控制或查询 GPIO 管脚。wiringPi 是可以扩展的,可以利用 wiringPi 的内部模块扩展模拟量输入芯片,可以使用 MCP23x17/MCP23x08(I2C 或者 SPI)扩展 GPIO 接口。另外可通过树莓派上的串口和 Atmega(例如 arduino 等)扩展更多的 GPIO 功能。另外,用户可以自己编写扩展模块并把自定义的扩展模块集成到 wiringPi 中。WiringPi 支持模拟量的读取和设置功能,不过在树莓派上并没有模拟量设备。但是使用 WiringPi 中的软件模块却可以轻松地应用 AD 或 DA 芯片。

wiringPi 安装

  • 方案 A——使用 GIT 工具,通过 GIT 获得 wiringPi 的源代码。
git clone git://git.drogon.net/wiringPi
cd wiringPi
./build

build 脚本会帮助你编译和安装 wiringPi。

tar xfz wiringPi-xx.tar.gz
cd wiringPi-xx
./build

测试

wiringPi 包括一套 gpio 命令,使用 gpio 命令可以控制树莓派上的各种接口,通过以下指令可以测试wiringPi 是否安装成功。

$gpio -v
$gpio readall

即可出现上面的 io 图。

例子

[cpp] view plaincopy 在 CODE 上查看代码片派生到我的代码片

#include <wiringPi.h>    
int main(void)    
{    
  wiringPiSetup() ;    
  pinMode (0, OUTPUT) ;    
  for(;;)     
  {    
    digitalWrite(0, HIGH) ; delay (500) ;    
    digitalWrite(0,  LOW) ; delay (500) ;    
  }    
}   

编译运行

在树莓派上:

gcc -Wall -o test test.c -lwiringPi 
sudo ./test

在虚拟机中:

am-linux-gcc -Wall -o test test.c -lwiringPi 
sudo ./test

注意事项:

  • IO 的编号方式略有不同,采用 wiring 编码方式。
  • -lwiringPi 表示动态加载 wiringPi 共享库。

BCM2835 C Library

  • 下载:$ wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.35.tar.gz
  • 解压缩:$tar xvzf bcm2835-1.35.tar.gz
  • 进入压缩之后的目录:$cd bcm2835-1.35
  • 配置:$./configure
  • 从源代码生成安装包:$make
  • 执行检查:$sudo make check
  • 安装 bcm2835库:$sudo make install
  • 例子[cpp] view plaincopy 在 CODE 上查看代码片派生到我的代码片
#include <bcm2835.h>    

// P1插座第11脚    
#define PIN RPI_GPIO_P1_11    

int main(int argc, char **argv)    
{    
  if (!bcm2835_init())    
  return 1;    

  // 输出方式    
  bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_OUTP);    

  while (1)    
  {    
    bcm2835_gpio_write(PIN, HIGH);    
    bcm2835_delay(100);    

    bcm2835_gpio_write(PIN, LOW);    
    bcm2835_delay(100);    
  }    
  bcm2835_close();    
  return 0;    
}   

注意事项:

  • IO 的编号方式略有不同,采用 wiring 编码方式。
  • -lwiringPi 表示动态加载 wiringPi 共享库。

转载自:

http://wiki.jikexueyuan.com/project/raspberry-pi/gpio.html

 

 

 

树莓派-简单入门

前言

我一直梦想着能够做出一款自制的飞行器,然后带着它游历世界各地,拍摄各种好玩的照片。听说树莓派似乎可以将我的编程专业发挥出来,既然如此,那么就开干吧。

那么就从环境的搭建开始做起,并以此博客作为记录和总结,也方便各位树莓派以及飞行器爱好者参考和借鉴。此外,我写的代码都会公开出来,方便大家探讨。

当然,本人初学者更希望有各路大神指点指点。

树莓派(Raspberry Pi)是学习计算机知识、架设服务器的好工具,价格低廉,可玩性高。

本文根据我的亲身经验,介绍如何从零开始,搭建一个树莓派服务器,控制 LED 灯。你会看到,树莓派玩起来实在很容易。

一、型号

树莓派是一个迷你电脑,集成在一块电路板。目前,最新的型号有两个。

(1)Raspberry Pi 3代 B 型

 

(2)Raspberry Pi zero (含 zero w)

虽然后者便宜,但是少了许多接口(比如只有一个 USB 口),CPU 和内存都比较低,配件也少,因此推荐购买第3代的 B 型。以下都针对这个型号,但大部分内容对 zero 也适用。

二、配件

树莓派本身只是一个主机。要运行起来,必须有配件。

(1)电源

Micro USB 接口的手机充电器,就可以充当电源,但输出必须是 5V 电压、至少 2A 电流。充电宝当电源也没问题。

(2)Micro SD 卡

树莓派不带硬盘,Micro SD 卡就是硬盘。最小容量8G,推荐使用16G和32G的卡。

(3)显示器

树莓派有 HDMI 输出,显示器必须有该接口。如果有 HDMI 转 VGA 的转接线,那么 VGA 显示器也可以。我用的是一个 7 寸的液晶监视器。

不过,显示器只在安装系统时需要,后面可以 SSH登录 ,所以就不需要了。

(4)无线键鼠

树莓派内置蓝牙,USB 或蓝牙的无线键鼠都可以用。

就像显示器一样,如果树莓派已经装好系统,而且只当作服务器,无线键鼠也可以不配。

三、电子元件

除了配件,下面的实验还需要一些电子元件。

(1)面包板(一块)

(2)连接线(若干)

注意,连接线必须一端是公头,一端是母头。

另外,最好也备一些两端都是公头的连接线。

(3)LED 二极管(若干)

(4)270欧姆的电阻(若干)

四、安装系统

如果商家已经装好系统,可以跳过这一步,否则需要自己安装操作系统。

官方提供的操作系统是 Raspbian,这是 Debian 系统的定制版。

官方还提供一个安装器 NOOBS,建议通过它来安装 Raspbian,相对简单一点。

下载 NOOBS。
格式化 Micro SD 卡为 FAT 格式(操作指导)。
解压NOOBS.zip到 Micro SD 卡根目录。
插入 Micro SD 卡到树莓派底部的卡槽,接通电源,启动系统。

正常情况下,按照屏幕上的提示,一路回车,就能装好系统。

五、SSH 登录

安装系统后,树莓派就可以上网了(Wifi 或者网线)。这时,你要看一下它的局域网 IP 地址,可以使用下面的命令。

$ sudo ifconfig

然后,更改系统设置,打开 SSH 登录(默认是禁止的)。

接着,从另一台电脑 SSH 登录树莓派。下面的命令是在局域网的另一台电脑上执行的。

$ ssh [email protected]

上面代码中,192.168.1.5是我的树莓派的地址,你要换成你的地址。树莓派的默认用户是pi

树莓派会提示你输入密码。pi的默认密码是raspberry。正常情况下,这样就可以登录树莓派了。接着,就可以进行各种服务器操作了,比如修改密码。

$ passwd

后面的实验需要将用户加入gpio用户组。

$ sudo adduser pi gpio

上面的代码表示将用户pi加入gpio用户组。

六、安装 Node

为了运行 Node 脚本,树莓派必须安装 Node,可以参考这篇文章

$ curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
$ sudo apt install nodejs

正常情况下,Node 8.x 版就已经安装成功了。

$ node -v
v8.1.0

七、点亮 LED

树莓派提供了一组对外的 IO 接口,称为 GPIO( 通用 IO 接口,General-purpose input/output)。

GPIO基本介绍

GPIO(General Purpose I/O Ports)意思为通用输入/输出端口,通俗地说,就是一些引脚,可以通过它们输出高低电平或者通过它们读入引脚的状态-是高电平或是低电平。GPIO是个比较重要的概念,用户可以通过GPIO口和硬件进行数据交互(如UART),控制硬件工作(如LED、蜂鸣器等),读取硬件的工作状态信号(如中断信号)等。GPIO口的使用非常广泛。掌握了GPIO,差不多相当于掌握了操作硬件的能力。

它的 40 个脚的定义如下图。

注意,左上角的第1针(3.3V)是一个方块,其他针脚都是圆的。将树莓派翻过来,背后可以看到 GPIO 有一个角是方的,通过这种方法就可以确认哪一个针眼是3.3V。

补充: 3.3v和5v代表着该针脚会输出3.3v和5v的电压,Ground代表着该针脚是接地的,GPIO0*则是一些待用户开发的针脚。每个针脚都可以使用程序进行控制操作。ground 代表 接地。

通过 GPIO ,树莓派可以与其他电子元件连接。下面根据 Jonathan Perkin 的文章,使用树莓派连接 LED 二极管。

这里需要用到面包板。本质上,面包板就是几根导线,上面开了许多可以连到导线的孔。

+极和-极是两根垂直的导线,标着1510这些数字的行,每一行都是一根水平的导线。导线与导线之间互不连接,另外,面包板的左右两半也是互不连接的。

然后,按照下面的图,将树莓派、面包板、LED 灯、电阻连起来。

上图中,红色导线表示电流的正极,从 GPIO 的第1针(3.3V)连到面包板。黑色导线表示电流的负极,从 GPIO 第三排的第6针(ground)连到面包板。它们连到面包板的哪个眼并不重要,但必须保证能组成一个完整的电路(上图的箭头流向)。注意,LED 二极管也有正负极,长脚表示正极,短脚表示负极。电阻没有正负极。

连接完成后,打开树莓派的电源,LED 应该就会亮起来了。

八、LED 控制脚本

下面,我们使用 Node 脚本控制 LED。

首先,将正极的导线从1号针脚(3.3V)拔出,插到第6排的11号针脚(上图的 GPIO 17)。这个针脚的电流是脚本可以控制的。

然后,在树莓派上新建一个实验目录,并安装控制 GPIO 的 Node 模块rpio。。

$ mkdir led-demo && cd led-demo
$ npm init -y
$ npm install -S rpio

接着,新建一个脚本led-on.js

// led-on.js
var rpio = require('rpio');

// 打开 11 号针脚(GPIO17) 作为输出
rpio.open(11, rpio.OUTPUT);

// 指定 11 号针脚输出电流(HIGH)
rpio.write(11, rpio.HIGH);

运行这个脚本,应该就会看到 LED 灯泡变亮了。

$ node led-on.js

再新建一个led-off.js脚本,只要改一行就行。

var rpio = require('rpio');

// Configure pin 11 (GPIO17) for output (i.e. read/write).
// rpio.setOutput(11);
rpio.open(11, rpio.OUTPUT);


// 指定 11 号针脚停止输出电流(LOW)
// Turn GPIO17 off, also known as 'LOW'.
rpio.write(11, rpio.LOW);

运行这个脚本,LED 灯泡应该就会熄灭了。

$ node led-off.js

有了这两个脚本,让 LED 闪烁就轻而易举了。新建一个led-blink.js脚本。

var rpio = require('rpio');

rpio.open(11, rpio.OUTPUT);

/*
 * Blink the LED quickly (10 times per second).  It is switched on every
 * 100ms, and a timeout is set for 50ms later to switch it off, giving us
 * the regular blink.
 */
setInterval(function blink() {
	rpio.write(11, rpio.HIGH);
	setTimeout(function ledoff() {
		rpio.write(11, rpio.LOW);
	}, 50);
}, 100);

上面的脚本让 LED 每秒闪烁10次。

$ node led-blink.js

九、HTTP 服务器

通过控制 LED 可以做很多事,比如架设一个 HTTP 服务器,每当有人访问,LED 就闪烁一下。

首先,在刚才的目录里面装一个服务器模块。

$ npm install -S server

然后,新建一个脚本server.js

var server = require('server');
var { get } = server.router;

var rpio = require('rpio');

rpio.open(11, rpio.OUTPUT);

function blink() {
  rpio.write(11, rpio.HIGH);
  setTimeout(function ledoff() {
    rpio.write(11, rpio.LOW);
  }, 50);
}

server({ port: 8080 }, [
  get('/' ,  ctx => {
    console.log('a request is coming...');
    blink();
  }),
]);

console.log('server starts on 8080 port');

运行这个脚本。

$ node server.js

然后,再打开一个命令行终端,访问8080端口,LED 就会闪一下。

$ curl http://localhost:8080

好了,今天的教程就到这里。接下来,你可以自己探索,做更多的尝试,比如写一个测试用例脚本,只要测试失败 LED 就会长亮,或者组装一个8位的加法器

 

 


python控制GPIO(教程可能是树莓派2的引脚,自己注意一下)

想用python来控制GPIO,最便捷的办法就是使用一些python类库,比如树莓派系统本身集成的RPi.GPIO。本文详细介绍如何使用RPi.GPIO来控制GPIO。

导入RPi.GPIO模块

可以用下面的代码导入RPi.GPIO模块。

import RPi.GPIO as GPIO

引入之后,就可以使用GPIO模块的函数了。如果你想检查模块是否引入成功,也可以这样写:

try:
    import RPi.GPIO as GPIO
except RuntimeError:
    print("引入错误")

针脚编号

在RPi.GPIO中,同时支持树莓派上的两种GPIO引脚编号。第一种编号是BOARD编号,这和树莓派电路板上的物理引脚编号相对应。使用这种编号的好处是,你的硬件将是一直可以使用的,不用担心树莓派的版本问题。因此,在电路板升级后,你不需要重写连接器或代码。

第二种编号是BCM规则,是更底层的工作方式,它和Broadcom的片上系统中信道编号相对应。在使用一个引脚时,你需要查找信道号和物理引脚编号之间的对应规则。对于不同的树莓派版本,编写的脚本文件也可能是无法通用的。

你可以使用下列代码(强制的)指定一种编号规则:

GPIO.setmode(GPIO.BOARD)
  # or
GPIO.setmode(GPIO.BCM)

下面代码将返回被设置的编号规则

mode = GPIO.getmode()

警告

如果RPi.GRIO检测到一个引脚已经被设置成了非默认值,那么你将看到一个警告信息。你可以通过下列代码禁用警告:

GPIO.setwarnings(False)

引脚设置

在使用一个引脚前,你需要设置这些引脚作为输入还是输出。配置一个引脚的代码如下:

# 将引脚设置为输入模式
GPIO.setup(channel, GPIO.IN)

# 将引脚设置为输出模式
GPIO.setup(channel, GPIO.OUT)

# 为输出的引脚设置默认值
GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)

释放

一般来说,程序到达最后都需要释放资源,这个好习惯可以避免偶然损坏树莓派。释放脚本中的使用的引脚:

GPIO.cleanup()

注意,GPIO.cleanup()只会释放掉脚本中使用的GPIO引脚,并会清除设置的引脚编号规则。

输出

要想点亮一个LED灯,或者驱动某个设备,都需要给电流和电压他们,这个步骤也很简单,设置引脚的输出状态就可以了,代码如下:

GPIO.output(channel, state)

状态可以设置为0 / GPIO.LOW / False / 1 / GPIO.HIGH / True。如果编码规则为,GPIO.BOARD,那么channel就是对应引脚的数字。

如果想一次性设置多个引脚,可使用下面的代码:

chan_list = [11,12]
GPIO.output(chan_list, GPIO.LOW)
GPIO.output(chan_list, (GPIO.HIGH, GPIO.LOW))

你还可以使用Input()函数读取一个输出引脚的状态并将其作为输出值,例如:

GPIO.output(12, not GPIO.input(12))

读取

我们也常常需要读取引脚的输入状态,获取引脚输入状态如下代码:

GPIO.input(channel)

低电平返回0 / GPIO.LOW / False,高电平返回1 / GPIO.HIGH / True。

如果输入引脚处于悬空状态,引脚的值将是漂动的。换句话说,读取到的值是未知的,因为它并没有被连接到任何的信号上,直到按下一个按钮或开关。由于干扰的影响,输入的值可能会反复的变化。
使用如下代码可以解决问题:

GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
  # or
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

需要注意的是,上面的读取代码只是获取当前一瞬间的引脚输入信号。

如果需要实时监控引脚的状态变化,可以有两种办法。最简单原始的方式是每隔一段时间检查输入的信号值,这种方式被称为轮询。如果你的程序读取的时机错误,则很可能会丢失输入信号。轮询是在循环中执行的,这种方式比较占用处理器资源。另一种响应GPIO输入的方式是使用中断(边缘检测),这里的边缘是指信号从高到低的变换(下降沿)或从低到高的变换(上升沿)。

轮询方式

while GPIO.input(channel) == GPIO.LOW:
    time.sleep(0.01)  # wait 10 ms to give CPU chance to do other things

边缘检测

边缘是指信号状态的改变,从低到高(上升沿)或从高到低(下降沿)。通常情况下,我们更关心于输入状态的该边而不是输入信号的值。这种状态的该边被称为事件。
先介绍两个函数:

  • wait_for_edge() 函数。
    wait_for_edge()被用于阻止程序的继续执行,直到检测到一个边沿。也就是说,上文中等待按钮按下的实例可以改写为
channel = GPIO.wait_for_edge(channel, GPIO_RISING, timeout=5000)
if channel is None:
    print('Timeout occurred')
else:
    print('Edge detected on channel', channel)
  • add_event_detect() 函数
    该函数对一个引脚进行监听,一旦引脚输入状态发生了改变,调用event_detected()函数会返回true,如下代码:
GPIO.add_event_detect(channel, GPIO.RISING)  # add rising edge detection on a channel
do_something()
// 下面的代码放在一个线程循环执行。
if GPIO.event_detected(channel):
    print('Button pressed')

上面的代码需要自己新建一个线程去循环检测event_detected()的值,还算是比较麻烦的。

不过可采用另一种办法轻松检测状态,这种方式是直接传入一个回调函数:

def my_callback(channel):
    print('This is a edge event callback function!')
    print('Edge detected on channel %s'%channel)
    print('This is run in a different thread to your main program')

GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback)

如果你想设置多个回调函数,可以这样:

def my_callback_one(channel):
    print('Callback one')

def my_callback_two(channel):
    print('Callback two')

GPIO.add_event_detect(channel, GPIO.RISING)
GPIO.add_event_callback(channel, my_callback_one)
GPIO.add_event_callback(channel, my_callback_two)

注意:回调触发时,并不会同时执行回调函数,而是根据设置的顺序调用它们。

综合例子:点亮LED灯

好了,上面说明了一大堆函数库的用法,那么现在就应该来个简单的实验了。这个实验很简单,点亮一个LED灯。

  • 编写代码之前,首先你需要将led灯的针脚通过杜邦线连接到树莓派的引脚上,比如你可以连接到11号引脚。
  • 新建一个main.py文件,写入如下代码:
import RPi.GPIO as GPIO  //引入函数库
import time

RPi.GPIO.setmode(GPIO.BOARD)  //设置引脚编号规则
RPi.GPIO.setup(11, RPi.GPIO.OUT)    //将11号引脚设置成输出模式

while True
    GPIO.output(channel, 1)   //将引脚的状态设置为高电平,此时LED亮了
    time.sleep(1)   //程序休眠1秒钟,让LED亮1秒
    GPIO.output(channel, 0)   //将引脚状态设置为低电平,此时LED灭了
    time.sleep(1)   //程序休眠1秒钟,让LED灭1秒

GPIO.cleanup()    //程序的最后别忘记清除所有资源
  • 保存,并退出文件。执行python3 main.py,即可观看效果。Ctrl+C可以关闭程序。
  • 此外,不妨也试试其它的函数吧,增强印象。

使用PWM

这个python函数库还支持PWM模式的输出,我们可以利用PWM来制作呼吸灯效果。详情看代码:

import time
import RPi.GPIO as GPIO   //引入库
GPIO.setmode(GPIO.BOARD)  //设置编号方式
GPIO.setup(12, GPIO.OUT)  //设置12号引脚为输出模式

p = GPIO.PWM(12, 50)  //将12号引脚初始化为PWM实例 ,频率为50Hz
p.start(0)    //开始脉宽调制,参数范围为: (0.0 <= dc <= 100.0)
try:
    while 1:
        for dc in range(0, 101, 5):
            p.ChangeDutyCycle(dc)   //修改占空比 参数范围为: (0.0 <= dc <= 100.0)
            time.sleep(0.1)
        for dc in range(100, -1, -5):
            p.ChangeDutyCycle(dc)
            time.sleep(0.1)
except KeyboardInterrupt:
    pass
p.stop()    //停止输出PWM波
GPIO.cleanup()    //清除

结语

在文中,主要讲解了GPIO的概念,以及如何使用python操作GPIO。如果有条件,建议大家多动动手,你会收获不少满足感。我也是初学者,如果你有任何问题,大家一起探讨学习。
本文参考文档:https://sourceforge.net/p/raspberry-gpio-python/wiki/

本文转载自:

http://www.ruanyifeng.com/blog/2017/06/raspberry-pi-tutorial.html

http://blog.hyesheng.com/2016-09-01-raspberry02/