LVS负载均衡+动静分离+高可用(nginx+tomcat+keepalived)

一、环境介绍

基于LVS(linux virtual server)linux虚拟服务器的http集群搭建
环境:使用VMware pro10,CentOS6.5
一共使用4台虚拟机,两台安装Ngnix,两台安装tomcat。
这四台服务器的作用分别是:其中一台nginx作为主服务器,另一台nginx_bk作为备用服务器,然后两台安装tomcat的虚拟机作为调度服务器。
安装并克隆虚拟机后,将四台虚拟机重新命名,分别命名为nginx, nginx_bk,server1,server2:

四台虚拟机的ip地址分别如下:

centOS_nginx 192.168.20.2.135
centOS_nginx_bk 192.168.20.2.139
CentOS_server1 192.168.20.2.134
CentOS+server2 192.168.20.2.137

未分类

二、环境安装

1、安装JDK

四台虚拟机均安装JDK,因安装过程是一样的,所以此处只截图一台虚拟机jdk安装过程。
首先查看jdk版本,centos默认安装openJDK:
未分类
检查可用的JDK版本:
[图片上传失败…(image-2ebecc-1512133579646)]

卸载原来openJDK
未分类
再次查看,已经卸载成功:
未分类
开始安装JDK,到oracle官网下载liunx jdk包,解压到当前目录下
解压好,进入目录查看:
未分类
配置JDK环境变量,修改/etc/profile
未分类
使环境变量生效:
未分类
参看结果:
未分类
此时可以看到jdk已经安装成功
这边liun下jdk的安装有很详细教程,可以去网上搜

2.两台服务器安装tomcat

下载tomcat,解压到/opt目录
解压后查看:
未分类
Root权限进入/bin目录,启动tomcat
未分类
配置防火墙端口:
未分类
未分类
重新加载防火墙配置:
未分类
未分类
启动tomcat访问,首页访问成功:

至此,tomcat安装完成,另一台server虚拟机可克隆该台虚拟机来实现。

3、nginx安装

下载nginx,解压到/usr/local目录下,解压后查看:
未分类
进入解压目录执行./configure命令进行安装
出现错误及解决方法:
错误1:
未分类
原因:缺少gc++
解决:
未分类
错误2:
未分类
解决:
未分类
错误3:
未分类
解决:
未分类
解决上述错误后,再执行安装命令:
未分类
查看nginx进程号:
未分类
启动nginx
未分类
关闭nginx命令是./nginx -s stop
默认端口是80,此时可在网页访问到:
未分类
至此,Nginx安装完成。

4、keepalive安装

Keepalived是一个基于VRRP协议来实现的服务高可用方案,作用是检测web服务器的状态,如果有一台web服务器死机,或工作出现故障,Keepalived将检测到,并将有故障的web服务器从系统中剔除,当web服务器工作正常后Keepalived自动将web服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的web服务器。
Keepalived实现服务的高可用(HA),应用已经非常广泛,很多软件都会和他搭配使,比如LVS,Nginx,Redis等
下载keepalie,解压到/opt/keepalive目录下
安装依赖插件:

yum install -y gcc openssl-devel popt-devel

编译安装:

./configure –prefix=/usr/local/keepalive
Make
Make install

编译之后的配置:
未分类
获得权限:
未分类
修改/etc/init.d/keepalived文件,将默认路径改成当前alive安装路径
未分类
即默认为前一行注释掉的路径,改为下一行,指向了正确的配置文件位置。

配置环境变量
未分类
建立软连接:
未分类
修改/usr/local/keepalive/etc/sysconfig/keepalived文件,修改正确的启动参数
未分类
启动Keepalived
未分类
设置keepalived服务为开机自启动
未分类
至此keepalived安装配置成功,另一两台nginx_bk可以克隆该台虚拟机。


其实在centos下可以直接用yum install keepalived来安装。默认安装路径为/etc/keepalived
用yum来装比较方便

三、负载均衡

现在有两台服务器192.168.204.134和192.168.204.137,服务器上各有一台tomcat,端口均为8080,在192.168.204上有Nginx
修改nginx安装目录中conf目录下的nginx.conf文件
主要配置信息如下:
未分类

补充知识了解:
nginx负载均衡到多台服务器上时,默认采用轮询策略:
常见策略:
1、轮询
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
2、weight
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况,数字越大命中率越高。
例如:轮询几率是2:1
upstream bakend {
server 192.168.0.14 weight=2;
server 192.168.0.15 weight=1;
}
2、ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
例如:
upstream bakend {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}

启动两台tomcat,重新启动nginx,访问192.168.204.135就会随机访问192.168.204.134和192.168.204.137
测试:
在两台tomcat服务器下webapps目录下创建文件夹21751152,新建index.html文件,index.html文件内容分别如下:
Server1下index.html文件:
未分类
Server2下index.html文件:
未分类
首先测试在两台tomcat服务器下本地能访问这两个页面:
Server1下:
未分类
Server2下:
未分类
可以看到两台服务下均可正常访问
然后在安装Nginx服务器下测试:
未分类
未分类
可以看到,在nginx服务器下,在网页中每次刷新都会随机访问到两台Tomcat服务器中的任意一台,可以看出,已经完成了负载均衡的效果。

四、动静分离

为了提高网站的响应速度,减轻程序服务器(tomcat)的负载,对于js,css,图片等静态文件可以在nginx反向代理服务器中进行缓存,这样浏览器在请求一个静态资源的时候,代理服务器就可以直接处理,而不用将请求转发给后端服务器。而用户请求的动态文件比如jsp则会转发给tomcat服务器处理,这就是动静分离,也是反向服务器的一个重要作用。
在server1这台服务器webapp/21751152目录下建index.jsp文件:
Index.jsp内容如下:
未分类
然后进行Nginx.conf配置文件的修改:
主要修改内容如下:
未分类
Root /usr/local/webapps 这段代码的意思是指定Nginx访问的目录,即静态资源所在的目录。

Expires 30d.指这些资源文件在客户端浏览器的缓存时间,30d值30天,1h指一小时
开始测试:
首先在server1本地进行测试,页面可以正常访问:
未分类
然后在nginx服务器下进行测试:
未分类
可以看到,向日葵这张图片作为静态文件,没被加载出来。这是因为静态资源访问请求已经被Nginx拦截,由Nginx进行处理。但是Nginx服务器的 /usr/local/webapps 目录下并没有图片资源,所以图片没有加载出来。index.jsp页面能够显示,说明动态的请求已经转发到了Tomcat,Tomcat对index.jsp进行了解析。
在Nginx服务器 /usr/local/webapps 目录下放置图片文件,将tomcat上把21751152/img/flower.jpg整个目录拷贝到其中。然后再次刷新。
未分类
未分类
此时,图片就被加载出来了。至此,可以看出已经Nginx已经实现了动静分离的功能。
在配置动静分离后,用户请求你定义的静态资源,默认会去nginx的发布目录请求,而不会到后端请求,这样可以提高网站响应速度,减轻真实Web服务器的负载压力。
不过在开发环境下,为了便于开发,咱们的静态资源和代码还是放在一起的,等开发测试完成,才会将完成的完整程序部署到生成环境上,然而程序代码和静态资源是分别放置到不同的服务器上的。

五、keepalive高可用

编辑ngin服务器的keepalived.conf文件,keepalived.conf文件如下图所示:
未分类
未分类
画出红线部分是主要需要注意的地方
备份的nginx_bk配置文件与此类似
需要注意的以下几个点:
需要修改state为BACKUP , priority比MASTER低,virtual_router_id和master的值一致
配置文件如下:
未分类
未分类
注:在主备机中vip应设置一致

1、遇到的问题1及解决过程

用keepalived方式在主nginx服务器中添加了虚拟Ip,但是用ip addr查看发现仍然只有一个IP地址,即keepaLived.cof文件里面配置的vip没有起到效果
未分类
解决问题过程:
(1)尝试一:
可能是keepalived没有安装成功,所以采用yum重新安装keepalived
但是重装后还是发现VIP没有生效。
(2)最终解决:
后来在同学的提醒下,发现是自己的keepalived服务没有启动好,nginx服务也需要重启。这两个服务启动好后,就可以了。
开始测试:
在两台nginx和nginx_bk服务器中keepalived服务和nginx服务都开启的情况下:
首先测试nginx的IP:
未分类
可以看到在Nginx中已经有虚拟ip了
而在Nginx_bk服务器中:
未分类
可以看到没有绑定虚拟ip
访问192.168.204.177
未分类
未分类
这是访问虚拟ip地址,发现也被转发到了Nginx主机192.168.204.135指向的tomcat服务器上,同时也是随机分配到了两天Tomcat服务器上,即实现了负载均衡。

2、遇到的问题2及解决过程

Nginx主从机器没有顺利切换
在模仿Nginx主机宕机过程中:
用service keepalived stop 命令将Nginx主机服务的keepalived服务停止。
未分类
可以看到虚拟ip就没有绑在主机上
此时再去查看nginx_bk服务器,按道理来说此时Nginx_bk这台机器上应该会绑定vip,但实际查看的时候,发现并没有绑定过来
解决过程:
(1) 尝试1
因为nginx_bk这台服务器是我克隆nginx主机这台虚拟机得到的,所以存在mac地址冲突问题,猜想可能是这个原因导致的无法主从切换。
所以我对nginx_bk这台虚拟机重新生成了mac地址
过程如下:
首先关闭该虚拟机
然后选中该虚拟机点击“设置”,选择“网络适配器”,“高级”
未分类
然后点击“生成”
未分类
这样就重新生成了一个MAC地址。
然后对该虚拟重启后,重新启动keepalived,nginx等服务,发现还是无法正常切换
(2) 尝试2
因为我的几台虚拟机都没有设置静态IP,在同学的建议下,可能是没有设置静态IP导致的问题,所以我对nginx和nginx_bk这两台服务器都设置了静态ip,
设置过程如下:
Nginx主机:
未分类
未分类
对Nginx_bk服务器静态地址设置与此类似

如上设置了静态IP后,问题还是没有得到解决。
但是在多次尝试中,意外发现,当把nginx_bk这台虚拟机的nginx服务关闭后,两台虚拟机之间的主从关系是能够体现的
即当nginx主机中keepalive和nginx服务都正常开启的情况下,nginx主机下绑定了192.168.204.177这个Vip
未分类
当nginx_bk主机中keepaliv服务正常开启的情况下,而nginx服务停止的情况下,该虚拟机是没有绑定虚拟ip的
未分类
然后将nginx主机的keepalived服务停止时:
未分类
如上两张图所示:
主机下绑定的vip已经漂移到了nginx_bk这台主机上
然后此时把nginx_bk这台主机上的nginx服务启动,发现在浏览器上访问vip地址时也顺利转发到了两台tomcat服务器上。
未分类
这时再把nginx主机上的keepalive重新启动,同时关闭nginx_bk主机上的nginx服务
未分类
此时nginx主机上又重新绑定了vip,同时网页也恢复了访问。
再去查看nginx_bk主机情况:
未分类
Nginx_bk上仍然定着vip,当把nginx主机重启后,在该虚拟机上通过vip也能访问到两台tomcat上的内容。
未分类
所以在这种情况下相当于两台nginx都同时被作为了访问入口。
最终我没有把该问题很好的解决掉,猜测的原因可能与Nginx有关。可能会在后期继续研究这个问题

参考博客:
http://www.cnblogs.com/mrlinfeng/p/6146866.html
http://blog.csdn.net/u010028869/article/details/50612571
上述的实现过程我主要参照了这两篇博客,感谢他们的无私分享。

Tomcat日志切割工具 logrotate

tomcat

  • Tomcat日志切割工具 logrotate
    一、日志工具Logrotate简介
    二、Logrotate运行机制
    三、Logrotate组成
    四、安装配置Logrotate
    五、测试

在我们生产环境中经常遇到tomcat log清理的问题,曾经做过实验通过重定向的方式把日志清空,但是发现日志tomcat里面的catalina.out不输出日志了。这时候我们可以考虑一下日志管理工具Logrotate
未分类

一、日志工具Logrotate简介

  1. Logrotate实际就是起着上述脚本作用的小工具,他通过让用户来配置规则的方式,检测和处理日志文件。配合Cron可让处理定时化;
  2. Logrotate预制了大量判断条件和处理方式,可大大降低手写脚本的负担和出错的可能;
  3. Logrorate检测日志文件属性,比对用户配置好的检测条件,对满足条件的再根据用户配置的要求来处理,整个可以通过Cron来定时调度,这其实是非常经典的Linux解决问题的思路,可以好好静下心来品味下,简单,好用。

二、Logrotate运行机制

系统会定时运行logrotate,一般是每天一次。系统是这么实现按天执行的。crontab会每天定时执行/etc/cron.daily目录下的脚本,而这个目录下有个文件叫logrotate

[root@ldap01 ~]# cat /etc/cron.daily/logrotate
#!/bin/sh
/usr/sbin/logrotate /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
    /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0

三、Logrotate组成

以下是logrotate运行的关键点:

/usr/bin/logrotate 程序所在位置;
/etc/cron.daily/logrotate 默认让Cron每天执行logrotate一次;
/etc/logrotate.conf 全局配置文件;
/etc/logrotate.d 应用自个的配置文件存放目录,覆盖全局配置;

四、安装配置Logrotate

安装logrotate

[root@localhost ~]# yum install -y logrotate

配置文件logrotate

[root@localhost ~]# cat /etc/logrotate.d/tomcat
/application/tomcat/logs/catalina.out {
    daily
    copytruncate
    rotate 30
    compress
    notifempty
    dateext
    missingok
}

关于每个参数的作用我们可以查看全局文件cat /etc/logrotate.conf 我们可以把配置文件写在/etc/logrotate.conf里面或者放在/etc/logrotate.d下面

配置文件参数解释

daily           表示每天整理一次    
rotate 20       表示保留20天的备份文件
dateext         文件后缀是日期格式,也就是切割后文件是:xxx.log-20171205.gz
copytruncate    用于还在打开中的日志文件,把当前日志备份并截断
compress        通过gzip压缩转储以后的日志(gzip -d xxx.gz解压)
missingok       如果日志不存在则忽略该警告信息
notifempty      如果是空文件的话,不转储
#size 5M                #当catalina.out大于5M就进行切割,可用可不用!

以下是不常用参数

1. weekly            指定转储周期为每周
2. monthly           指定转储周期为每月
3. nocompress        不需要压缩时,用这个参数 
4. nocopytruncate    备份日志文件但是不截断
5. create mode owner group   转储文件,使用指定的文件模式创建新的日志文件
6. nocreate          不建立新的日志文件
7. delaycompress 和 compress    一起使用时,转储的日志文件到下一次转储时才压缩
8. nodelaycompress     覆盖 delaycompress 选项,转储同时压缩
9. errors address     转储时的错误信息发送到指定的Email 地址
10. ifempty     即使是空文件也转储,这个是 logrotate 的缺省选项。
11. mail address     把转储的日志文件发送到指定的E-mail 地址
12. nomail      转储时不发送日志文件
13. olddir directory      转储后的日志文件放入指定的目录,必须和当前日志文件在同一个文件系统 
14. noolddir      转储后的日志文件和当前日志文件放在同一个目录
15. prerotate/endscript     在转储以前需要执行的命令可以放入这个对,这两个关键字必须单独成行
16. postrotate/endscript   在转储以后需要执行的命令可以放入这个对,这两个关键字必须单独成行

温馨提示:配置文件里一定要配置rotate 文件数目这个参数。如果不配置默认是0个,也就是只允许存在一份日志,刚切分出来的日志会马上被删除。

五、测试

# 1. 调试 (d = debug)参数为配置文件,不指定则执行全局配置文件
logrotate -d /etc/logrotate.d/tomcat.conf
# 2. 强制执行(-f = force),可以配合-v(-v =verbose)使用,注意调试信息默认携带-v;
logrotate -v -f /etc/logrotate.d/tomcat.conf

效果图如下:
未分类

这个工具会自动每天帮我们分隔日志并进行打包,不需要我们在写crontab的脚本,非常的好用!

VPS建站:Mysql数据库日志大量占用磁盘空间导致速度缓慢

故障记录,仅供参考!使用 Linode vps 完成建站并且使用时间超过一年以上的学员可以检查一下。

最近帮学员解答问题的时候发现有个学员用 Linode 建的网站,网站内容很多,有上百个产品也有不少 blog 文章(做内容营销的)。他反映,用了一年多了,网站的速度最近感觉明显很慢很慢。

重点检查了一下缓存插件,发现是正常的。但是 FQ 访问并操作的时候明显感觉到很慢。

最后发现是 Linode 的磁盘空间快要满了,硬盘空间少会会导致网站速度慢,如果空间已满,还会导致网站无法访问。

检查了一下原因,是因为以前安装 lnmp环境安装包的时候程序默认不关闭 Mysql 的日志文件,导致在 /usr/local/mysql/var/ 下生成了许多名为 mysql-bin.0000* 的日志文件,每一个日志文件的大小都有1G,时间久了会占用硬盘空间。因此我们需要清理这些文件。

首先,xshell 连接 Linode 后,

执行命令查看磁盘空间

df -h

接着会出现类似下面这样的信息:

[root@li1207-110 ~]# df -h
Filesystem      Size  Used  Avail Use%  Mounted on
/dev/sda        20G   15.5G  3.5G  80%  /
tmpfs           493M  192K   493M   1%  /dev/shm

这位学员用的是5美金方案的 Linode,SSD硬盘 20G 容量,已用了 15.5 G 以上。

我们用 XFTP 到 /usr/local/mysql/var/ 下看一下,确实有几个较大的名为 mysql-bin.0000* 的文件。如:mysql-bin.000015,mysql-bin.000016 等等。。

清理 MySQL 日志文件

执行:/usr/local/mysql/bin/mysql -u root -p

接着提示 Enter password:

输入数据库管理员密码(root password of Mysql Database),注意输入的时候是不显示输入状态的,字符不可见。所以你可以在记事本上先写好密码,然后复制,再鼠标右键粘贴进去,粘贴进去的时候也不显示,直接回车即可。

然后会提示:mysql>

未分类

此时复制并执行下面的命令,注意复制的时候要包含分号,粘贴,回车执行。

reset master;

执行完后会提示类似于:“Query OK, 234 rows affected (12.3 sec)”,说明已经成功。

再输入:quit 退出 mysql 命令模式。

此时在 XFTP 窗口中点击刷新按钮,可以看到 /usr/local/mysql/var/ 下的名为 mysql-bin.0000* 的日志文件已经清理掉。(注意其他的文件不要去手动删除)

我们再次执行 df -h 命令。

[root@li1207-110 ~]# df -h
Filesystem     Size   Used  Avail Use%  Mounted on
/dev/sda       20G    8G    10G   42%   /
tmpfs          493M   192K  493M  1%    /dev/shm

可以看到空余了不少磁盘空间。

定期自动清理MySQL日志

用 Xftp 连接打开 VPS 的根目录,找到根目录下的 etc 目录,在该目录下有个名为 my.cnf 的文件。这个文件即为 MySQL 数据库的配置( cnf=Configuration) 文件。

下载(或 vi 命令)用 notepad++ 修改编辑打开它,可以看到这一行:

expire_logs_days = 10

这是代表数据库日志文件过10天就失效并清理。如果你的网站流量很大(或者将来会流量很大),那么即使是 10天产生的日志文件也会很大。

因此我们可以把 10 改成 5。上传覆盖原 my.cnf 文件,然后重启 mysql。

service mysql restart

这样每过 5 天就会自动清理日志。

我们也可以彻底禁用 MySQL 日志。

彻底禁用MySQL日志

修改/etc/my.cnf 文件,找到

log-bin=mysql-bin
binlog_format=mixed

在这两行前面加上#,将其注释掉。上传覆盖原 my.cnf 文件,然后重启 mysql。

未分类

mysql 数据去重

从excel中导入了一部分数据到mysql中,有很多数据是重复的,而且没有主键,需要按照其中已经存在某一列对数据进行去重。

添加主键

由于之前的字段中没有主键,所以需要新增一个字段,并且将其作为主键。

添加一个新的字段id,对id中的值进行递增操作,然后再设置为主键。

对id字段进行递增的赋值操作如下:

SET @r:=0;
UPDATE table SET id=(@r:=@r+1);

然后设置为主键即可。

去重

添加玩递增的id字段后,就可以对数据根据某个字段进行去重操作,策略就是保存id最小的那条数据。

DELETE FROM `table`
WHERE
`去重字段名` IN (
    SELECT x FROM
    (
        SELECT `去重字段名` AS x 
        FROM `table` 
        GROUP BY `去重字段名` 
        HAVING COUNT(`去重字段名`) > 1
    ) tmp0
)
AND 
`递增主键名` NOT IN (
    SELECT y FROM
    (
        SELECT min(`递增主键名`) AS y 
        FROM `table` 
        GROUP BY `去重字段名` 
        HAVING COUNT(`去重字段名`) > 1
    ) tmp1
)

Linux下安装MongoDB的实现步骤

Linux下安装MongoDB的实现步骤

Mongo DB 是目前在IT行业非常流行的一种非关系型数据库(NoSql),其灵活的数据存储方式备受当前IT从业人员的青睐。Mongo DB很好的实现了面向对象的思想(OO思想),在Mongo DB中 每一条记录都是一个Document对象。Mongo DB最大的优势在于所有的数据持久操作都无需开发人员手动编写SQL语句,直接调用方法就可以轻松的实现CRUD操作。本文介绍了如何快速安装mongodb供大家参考。

一、安装配置mongodb

Step 1: 设置系统环境及确保缺省端口27107可用

###当前环境
# cat /etc/issue
Red Hat Enterprise Linux Server release 6.5 (Santiago)

# vi /etc/selinux/config
SELINUX=disabled

Step 2: 下载安装文件

下载地址: https://www.mongodb.org/downloads. 
或者直接在命令提示符下使用curl命令下载
curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.6.tgz

Step 3: 解压下载的文件

# pwd
/usr/local/src
# tar -xvf mongodb-linux-x86_64-rhel62-3.0.6.gz ###注,本文直接从网站下载,所以文件为.gz

Step 4: 复制解压文件到运行目录

# mkdir -p /var/lib/mongodb
# cp -R -n /usr/local/src/mongodb-linux-x86_64-rhel62-3.0.6/. /var/lib/mongodb/

Step 5: 设置环境变量

e.g. export PATH=<mongodb-install-directory>/bin:$PATH
# vi ~/.bash_profile 
 export PATH=/var/lib/mongodb/bin:$PATH
# source ~/.bash_profile

Step 6: 创建数据目录

# mkdir -p /data/mongodata

二、启动及验证mongodb

###启动mongo
# mongod --dbpath /data/mongodata

###以下内容为启动后输出的相关信息
2015-10-28T10:03:33.100+0800 I JOURNAL [initandlisten] journal dir=/data/mongodata/journal
2015-10-28T10:03:33.101+0800 I JOURNAL [initandlisten] recover : no journal files present, no recovery needed
2015-10-28T10:03:33.264+0800 I JOURNAL [initandlisten] preallocateIsFaster=true 2.18
2015-10-28T10:03:33.398+0800 I JOURNAL [durability] Durability thread started
2015-10-28T10:03:33.398+0800 I JOURNAL [journal writer] Journal writer thread started
2015-10-28T10:03:33.401+0800 I CONTROL [initandlisten] MongoDB starting : pid=10191 port=27017 dbpath=/data/mongodata 64-bit host=java_2
2015-10-28T10:03:33.401+0800 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2015-10-28T10:03:33.401+0800 I CONTROL [initandlisten] 
2015-10-28T10:03:33.402+0800 I CONTROL [initandlisten] 
2015-10-28T10:03:33.402+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2015-10-28T10:03:33.402+0800 I CONTROL [initandlisten] **    We suggest setting it to 'never'
2015-10-28T10:03:33.402+0800 I CONTROL [initandlisten] 
2015-10-28T10:03:33.402+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2015-10-28T10:03:33.402+0800 I CONTROL [initandlisten] **    We suggest setting it to 'never'
2015-10-28T10:03:33.402+0800 I CONTROL [initandlisten] 
2015-10-28T10:03:33.402+0800 I CONTROL [initandlisten] db version v3.0.6
2015-10-28T10:03:33.402+0800 I CONTROL [initandlisten] git version: 1ef45a23a4c5e3480ac919b28afcba3c615488f2
2015-10-28T10:03:33.402+0800 I CONTROL [initandlisten] build info: Linux ip-10-67-194-123 2.6.32-220.el6.x86_64 #1 SMP Wed Nov 9 08:03:13 EST 2011 x86_64 BOOST_LIB_VERSION=1_49
2015-10-28T10:03:33.402+0800 I CONTROL [initandlisten] allocator: tcmalloc
2015-10-28T10:03:33.402+0800 I CONTROL [initandlisten] options: { storage: { dbPath: "/data/mongodata" } }
2015-10-28T10:03:33.404+0800 I INDEX  [initandlisten] allocating new ns file /data/mongodata/local.ns, filling with zeroes...
2015-10-28T10:03:33.491+0800 I STORAGE [FileAllocator] allocating new datafile /data/mongodata/local.0, filling with zeroes...
2015-10-28T10:03:33.491+0800 I STORAGE [FileAllocator] creating directory /data/mongodata/_tmp
2015-10-28T10:03:33.497+0800 I STORAGE [FileAllocator] done allocating datafile /data/mongodata/local.0, size: 64MB, took 0.001 secs
2015-10-28T10:03:33.511+0800 I NETWORK [initandlisten] waiting for connections on port 27017

###停止mongo,直接使用ctrl + c
^C2015-10-28T10:09:21.510+0800 I CONTROL [signalProcessingThread] got signal 2 (Interrupt), will terminate after current cmd ends
2015-10-28T10:09:21.511+0800 I CONTROL [signalProcessingThread] now exiting
2015-10-28T10:09:21.511+0800 I NETWORK [signalProcessingThread] shutdown: going to close listening sockets...
2015-10-28T10:09:21.511+0800 I NETWORK [signalProcessingThread] closing listening socket: 5
2015-10-28T10:09:21.511+0800 I NETWORK [signalProcessingThread] closing listening socket: 6
2015-10-28T10:09:21.511+0800 I NETWORK [signalProcessingThread] removing socket file: /tmp/mongodb-27017.sock
2015-10-28T10:09:21.511+0800 I NETWORK [signalProcessingThread] shutdown: going to flush diaglog...
2015-10-28T10:09:21.511+0800 I NETWORK [signalProcessingThread] shutdown: going to close sockets...
2015-10-28T10:09:21.512+0800 I STORAGE [signalProcessingThread] shutdown: waiting for fs preallocator...
2015-10-28T10:09:21.512+0800 I STORAGE [signalProcessingThread] shutdown: final commit...
2015-10-28T10:09:21.512+0800 I JOURNAL [signalProcessingThread] journalCleanup...
2015-10-28T10:09:21.512+0800 I JOURNAL [signalProcessingThread] removeJournalFiles
2015-10-28T10:09:21.515+0800 I JOURNAL [signalProcessingThread] Terminating durability thread ...
2015-10-28T10:09:21.615+0800 I JOURNAL [journal writer] Journal writer thread stopped
2015-10-28T10:09:21.615+0800 I JOURNAL [durability] Durability thread stopped
2015-10-28T10:09:21.615+0800 I STORAGE [signalProcessingThread] shutdown: closing all files...
2015-10-28T10:09:21.618+0800 I STORAGE [signalProcessingThread] closeAllFiles() finished
2015-10-28T10:09:21.618+0800 I STORAGE [signalProcessingThread] shutdown: removing fs lock...
2015-10-28T10:09:21.618+0800 I CONTROL [signalProcessingThread] dbexit: rc: 0

###修复启动过程中的两个警告,关于使用root用户启动mongo的警告先忽略
# echo "never" > /sys/kernel/mm/transparent_hugepage/enabled
# echo "never" > /sys/kernel/mm/transparent_hugepage/defrag

###再次重启,后置于后台进程,
# mongod --dbpath /data/mongodata &

###查看启动后的进程
# ps -ef|grep mongo |grep -v grep
root   11115 27956 0 10:11 pts/2  00:00:00 mongod --dbpath /data/mongodata
# lsof -i:27017
COMMAND  PID USER  FD  TYPE  DEVICE SIZE/OFF NODE NAME
mongod 11115 root  5u IPv4 50567119   0t0 TCP *:27017 (LISTEN)

###使用mongo连接到mongod
# mongo
MongoDB shell version: 3.0.6
connecting to: test
2015-10-28T10:14:30.685+0800 I NETWORK [initandlisten] connection accepted from 127.0.0.1:53907 #1 (1 connection now open)
Server has startup warnings: 
2015-10-28T10:11:49.217+0800 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2015-10-28T10:11:49.217+0800 I CONTROL [initandlisten] 
> help
    db.help()          help on db methods
    db.mycoll.help()       help on collection methods
    sh.help()          sharding helpers
    rs.help()          replica set helpers
    help admin          administrative help
    help connect         connecting to a db help
    help keys          key shortcuts
    help misc          misc things to know
    help mr           mapreduce


    show dbs           show database names
    show collections       show collections in current database
    show users          show users in current database
    show profile         show most recent system.profile entries with time >= 1ms
    show logs          show the accessible logger names
    show log [name]       prints out the last segment of log in memory, 'global' is default
    use <db_name>        set current database
    db.foo.find()        list objects in collection foo
    db.foo.find( { a : 1 } )   list objects in foo where a == 1
    it              result of the last line evaluated; use to further iterate
    DBQuery.shellBatchSize = x  set default number of items to display on shell
    exit             quit the mongo shell
> db.getCollection("version");
test.version
> exit
bye

三、mongodb相关工具

###在安装文件下有README,描述了常用的mongodb相关命令行工具
# more /usr/local/mongodb/README 
MongoDB README
Welcome to MongoDB!
COMPONENTS

 bin/mongod - The database process.
 bin/mongos - Sharding controller.
 bin/mongo - The database shell (uses interactive javascript).

UTILITIES

 bin/mongodump     - MongoDB dump tool - for backups, snapshots, etc..
 bin/mongorestore   - MongoDB restore a dump
 bin/mongoexport    - Export a single collection to test (JSON, CSV)
 bin/mongoimport    - Import from JSON or CSV
 bin/mongofiles    - Utility for putting and getting files from MongoDB GridFS
 bin/mongostat     - Show performance statistics

RUNNING

 For command line options invoke:

  $ ./mongod --help

 To run a single server database:

  $ mkdir /data/db
  $ ./mongod
  $
  $ # The mongo javascript shell connects to localhost and test database by default:
  $ ./mongo 
  > help

DRIVERS

 Client drivers for most programming languages are available at mongodb.org. Use the 
 shell ("mongo") for administrative tasks.

###获取单个命令用法
# <command> --help
# mongod --help|more
Options:

General options:
 -h [ --help ]        show this usage information
 --version          show version information

# mongod --version
db version v3.0.6
git version: 1ef45a23a4c5e3480ac919b28afcba3c615488f2

mongodb中save和update的区别

save:更新数据结构;
update:只更新数据。

mongodb数据如下(把status.arr更新成[3,2,1]):

{
    "_id" : 0,
    "status" : {
        "id" : 1,
        "username" : "root",
        "pass" : "123456",
        "msg" : "no",
        "arr" : [1,2,3]
    }
}

使用save更新数据

var otherData = {
    "_id" : 0,
    "status" : {
        "id" : 1,
        "username" : "root",
        "pass" : "123456",
        "msg" : "no",
        "arr" : [3,2,1]
    }
}
// 使用save方法会更新数据结构
// 所以更新一个数据需要把数据结构一起写好
mongodb.save(otherData,function(err,result){

})

使用update更新数据

mongodb.update({"_id":"0"},{$set:{"status.arr":[3,2,1]}},function(err,result){

})

mongodb禁止外网访问及添加账号的操作方法

那么我将从两个方面提高mongo数据库的安全防护系数

1. 设置mongodb外网禁止访问

启动数据库时,额外添加–bind_ip 127.0.0.1即可

./mongod --bind_ip 127.0.0.1 --dbpath /data/db --auth

也可以通过修改/etc/mongod.conf文件添加一行代码

#只监听本地接口,多个接口用,隔开

bind_ip = 127.0.0.1

2. 为数据库设置账号密码登录权限

为了保证数据库需要账号密码才能连接,那么在启动数据库的时候需要添加auth参数

./mongod --dbpath /data/db --auth

也可以通过修改/etc/mongod.conf文件添加一行代码

uth = true

这样在进行数据库连接的时候需要相应的账号密码才能成功访问。

如果之前数据库未设置账号密码的话,那么需要先添加一个管理员账户,

> use admin
switched to db admin
> db.createUser({user:"root",pwd:"123456",roles:["userAdminAnyDatabase"]})
Successfully added user: { "user" : "root", "roles" : [ "userAdminAnyDatabase" ] }

此时我们就成功的创建了一个管理员账户 账户名 root 密码 123456 ,此时执行show dbs会出现如下报错

> show dbs
2017-12-03T22:14:58.418+0800 E QUERY  [thread1] Error: listDatabases failed:{
  "ok" : 0,
  "errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }",
  "code" : 13,
  "codeName" : "Unauthorized"
} .....

上边提示意为当前admin数据库未经授权无法执行指令,因此需要以管理员身份登录验证,如下操作

> db.auth('dpd','123456')

上边执行登录操作,输出结果 1,说明登录成功。此时再执行 show dbs 则会成功输出结果。此刻我们是以管理员的身份登录数据库,如果切换到test数据库,执行db.blog.insert({name:1})会报错如下,同样意为该数据库未经授权无法操作:

> use test
switched to db test
> db.blog.insert({name:1})
WriteResult({
  "writeError" : {
    "code" : 13,
    "errmsg" : "not authorized on test to execute command { insert: "blog", documents: [ { _id: ObjectId('5a240d8e2d43081ea4271cc8'), name: 1.0 } ], ordered: true }"
  }
})

所以要为test数据库添加一个用户,并以该用户身份登录才可以执行对该数据的操作。

> db.createUser({user:'use1',pwd:'123456',roles:["readWrite"]})
Successfully added user: { "user" : "use1", "roles" : [ "readWrite" ] }
> db.auth('use1','123456')
1
> db.blog.insert({name:1})
WriteResult({ "nInserted" : 1 })
>

至此,完成了通过账号和密码登录权限对数据库的访问和操作。

那么最终标准的连接test数据库的URI语法如下:

mongodb://use1:123456@localhost:27017/test

总结

以上所述是小编给大家介绍的mongodb禁止外网访问及添加账号的操作方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!

CentOS6.x安装memcached-1.5.x

一、系统及安装说明

系统:CentOS6.x_x64,memcached-1.5.3。memcached官方下载地址 http://www.memcached.org/files/memcached-1.5.3.tar.gz。libevent 库:https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz

二、开始安装

1>首先yum安装gcc

yum install -y wget gcc

2>安装源码libevent库

#wget https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz
#tar zxvf libevent-2.0.21-stable.tar.gz
#./configure --prefix=/usr/local/libevent
#make && make install

检查是否安装成功

#输入: ls -al /usr/local/libevent/lib | grep libevent
#如果输出为下所示则表示安装成功
lrwxrwxrwx 1 root root      21 Dec  4 18:08 libevent-2.0.so.5 -> libevent-2.0.so.5.1.9
-rwxr-xr-x 1 root root  968442 Dec  4 18:08 libevent-2.0.so.5.1.9
-rw-r--r-- 1 root root 1571130 Dec  4 18:08 libevent.a
lrwxrwxrwx 1 root root      26 Dec  4 18:08 libevent_core-2.0.so.5 -> libevent_core-2.0.so.5.1.9
-rwxr-xr-x 1 root root  585057 Dec  4 18:08 libevent_core-2.0.so.5.1.9
-rw-r--r-- 1 root root  977914 Dec  4 18:08 libevent_core.a
-rwxr-xr-x 1 root root     985 Dec  4 18:08 libevent_core.la
lrwxrwxrwx 1 root root      26 Dec  4 18:08 libevent_core.so -> libevent_core-2.0.so.5.1.9
lrwxrwxrwx 1 root root      27 Dec  4 18:08 libevent_extra-2.0.so.5 -> libevent_extra-2.0.so.5.1.9
-rwxr-xr-x 1 root root  404772 Dec  4 18:08 libevent_extra-2.0.so.5.1.9
-rw-r--r-- 1 root root  593288 Dec  4 18:08 libevent_extra.a
-rwxr-xr-x 1 root root     992 Dec  4 18:08 libevent_extra.la
lrwxrwxrwx 1 root root      27 Dec  4 18:08 libevent_extra.so -> libevent_extra-2.0.so.5.1.9
-rwxr-xr-x 1 root root     950 Dec  4 18:08 libevent.la
lrwxrwxrwx 1 root root      29 Dec  4 18:08 libevent_openssl-2.0.so.5 -> libevent_openssl-2.0.so.5.1.9
-rwxr-xr-x 1 root root   94209 Dec  4 18:08 libevent_openssl-2.0.so.5.1.9
-rw-r--r-- 1 root root  131836 Dec  4 18:08 libevent_openssl.a
-rwxr-xr-x 1 root root    1021 Dec  4 18:08 libevent_openssl.la
lrwxrwxrwx 1 root root      29 Dec  4 18:08 libevent_openssl.so -> libevent_openssl-2.0.so.5.1.9
lrwxrwxrwx 1 root root      30 Dec  4 18:08 libevent_pthreads-2.0.so.5 -> libevent_pthreads-2.0.so.5.1.9
-rwxr-xr-x 1 root root   18462 Dec  4 18:08 libevent_pthreads-2.0.so.5.1.9
-rw-r--r-- 1 root root   18702 Dec  4 18:08 libevent_pthreads.a
-rwxr-xr-x 1 root root    1013 Dec  4 18:08 libevent_pthreads.la
lrwxrwxrwx 1 root root      30 Dec  4 18:08 libevent_pthreads.so -> libevent_pthreads-2.0.so.5.1.9
lrwxrwxrwx 1 root root      21 Dec  4 18:08 libevent.so -> libevent-2.0.so.5.1.9

3>下载安装memcached

#wget 
#tar -zxvf  memcached-1.5.3.tar.gz
#./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent
#make && make install
#ln -s /usr/local/memcached/bin/memcached /usr/local/bin   #建立软连接

三、编辑脚本加入启动项

1>脚本

vim cat /etc/init.d/memcached
#!/bin/sh
#
# memcached:    MemCached Daemon
#
# chkconfig:    - 90 25
# description:  MemCached Daemon
# Source function library.
# Author: pkey san 2015/12/07
. /etc/rc.d/init.d/functions
. /etc/sysconfig/network
prog=memcached
pidfile=${PIDFILE-/var/run/memcached.pid}
start()
{
        echo -n $"Starting memcached: "
        daemon --pidfile=${pidfile} /usr/local/bin/memcached -u daemon -d -m 512 -l 127.0.0.1 -c 4096 -p 11211
        echo `ps aux |grep memcached |grep 11211 |grep -v grep |awk '{print $2}'` >$pidfile
        echo
}
stop()
{
        echo -n $"Shutting down memcached: "
        killproc  $prog
        echo
}
rh_status(){
status -p ${pidfile} $prog
}
[ -f /usr/local/bin/memcached ] || exit 0
# See how we were called.
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  status)
        rh_status
        ;;
  restart|reload)
        stop
        start
        ;;
  *)
        echo $"Usage: $0 {start|stop|status|restart|reload|}"
        exit 1
esac
exit 0

2>解释说明

daemon --pidfile=${pidfile} /usr/local/bin/memcached -u daemon -d -m 512 -l 127.0.0.1 -c 4096 -p 11211     

-p memcached监听的TCP端口
-l 监听的ip地址,127.0.0.1是本机,当然也可以写上你的服务器IP,如:10.0.0.10,这是我服务器的IP地址,如果你需要多个服务器都能够读取这台memcached的缓存数据,那么就必须设定这个ip
-d 以daemon方式运行,将程序放入后台
-u memcached的运行用户
-P memcached的pid文件路径
-m memcached可以使用的最大内存数量
-c memcached同时可以接受的最大的连接数
如果你希望以socket方式来访问memcached,那么在启动的时候就必须去掉 -l和-p参数,并加上-s参数:
-s memcached的socket文件路径

3>添加开机启动

#chmod +x /etc/init.d/memcached
#chkconfig --add memcached
#chkconfig memcached on
#service memcached start|stop|restart|reload|status

四、编译配置(第二种启动方式)

#安装好之后
ln -s /usr/local/memcached/bin/memcached /usr/bin/memcached
/bin/cp scripts/memcached.sysv /etc/init.d/memcached
sed -i 's@^USER=.*@USER=root@' /etc/init.d/memcached
sed -i 's@chown@#chown@' /etc/init.d/memcached
sed -i 's@/var/run/memcached/memcached.pid@/var/run/memcached.pid@' /etc/init.d/memcached
sed -i 's@^prog=.*@prog="/usr/local/memcached/bin/memcached"@' /etc/init.d/memcached #前面有软链接,这里可以省略
chmod +x /etc/init.d/memcached
chkconfig --add memcached
chkconfig memcached on

此种方式也可以加到启动项里。

配置Memcached禁止公网访问

1. 修改memcached配置文件,添加OPTIONS的-l 127.0.0.1参数

    [root@iZbp include]# vim /etc/init.d/memcached
     11 PORT=11211
     12 USER=memcached
     13 MAXCONN=1024
     14 CACHESIZE=984
     15 OPTIONS="-l 127.0.0.1"
     16 DAEMON=/usr/local/memcached/bin/memcached

重启memcached服务

    [root@iZbp include]# service memcached restart
    Stopping memcached:                                        [  OK  ]
    Starting memcached:                                        [  OK  ]

2. 配置防火规则,仅仅允许本机的tcp、udp访问memcached的11211端口,拦截外部访问

accept规则

    # iptables -A INPUT -p tcp -s 127.0.0.1 --dport 11211 -j ACCEPT
    # iptables -A INPUT -p udp -s 127.0.0.1 --dport 11211 -j ACCEPT

drop规则

    # iptables -I INPUT -p tcp --dport 11211 -j DROP
    # iptables -I INPUT -p udp --dport 11211 -j DROP

保存规则并重启 iptables

    # service iptables save
    # service iptables restart

3. 办公电脑本机cmd命令行测试是否可以远程访问:

    telnet x.x.x.x 11211

提示11211端口连接失败,则表示配置成功,Server禁止远程访问memcached。

MEMCACHED的时间设置

1、过期时间限制

memcached的过期时间并不能随便设置,有一个最大时限就是30天,若超过30天后,存储时返回true,但是在取数据的时候取不到。(在取数据的时候才去做验证,看看数据是否失效)
说到这个过期时间了,就不得不说说memcached的缓存失效策略:
memcached的缓存失效策略是LRU(最近最少使用)加上到期失效策略。当向memcached存储数据时,你可能会设置一个过期时间,可以是永久也可以是一段时间,但是如果一旦给memcached分配的内存使用完毕,则首先会替换掉已失效的数据,其次是最近最少使用的数据。

2、存储限制

键被限制在 250 字符之内。数据项不能超过 1M (这个值由其内存分配机制决定的),因为这是最大的块( slab )值。如果对数据超过1M的值进行set,则会返回FALSE。
memcached默认情况下采用了名为Slab Allocator的机制分配、管理内存。在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的。但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached进程本身还慢。Slab Allocator就是为解决该问题而诞生的。Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块,以完全解决内存碎片问题.

3、访问限制

最大同时连接数200.