Haproxy和pacemaker结合corosync实现负载均衡高可用,以及crm命令的使用

实验之前需要将之间做的负载均衡和高可用软件全部关掉!!!!!
server1和server9上安装Haproxy:
server1:

安装见上篇博文:
scp haproxy-1.6.11-1.x86_64.rpm 172.25.92.9:/root
scp /etc/haproxy/haproxy.cfg 172.25.92.9:/etc/haproxy
scp /etc/security/limits.conf 172.25.92.9:/etc/security
vim /etc/haproxy/haproxy.cfg 
     37         bind            172.25.92.100:80 name clear     #设置只有访问172.25.92.100才能访问集群资源
/etc/init.d/haproxy start

server9:

 rpm -ivh haproxy-1.6.11-1.x86_64.rpm 
  groupadd -g 200 haproxy
  useragdd -u 200 -g 200 haproxy
 useradd -u 200 -g 200 haproxy
  id haproxy
vim /etc/haproxy/haproxy.cfg
    37         bind            172.25.92.100:80 name clear
/etc/init.d/haproxy start

测试:打开后端服务器server2和server3:
server1和server9:curl 172.25.92.100
可以看到server3的hph页面。(之前搭建的)

server1和server9安装pacemaker和corosync:
其中corosync再之前做RHCS套件时已经安装,因为RHCS套件的高可用也时利用corosync实现心跳检测。
server1:

yum install -y pacemaker corosync
/etc/init.d/corosync start
[root@server1 ~]# cd /etc/corosync/
[root@server1 corosync]# cp corosync.conf.example corosync.conf
[root@server1 corosync]# vim corosync.conf
10                 bindnetaddr: 172.25.92.0
 11                 mcastaddr: 226.94.1.92
 12                 mcastport: 5405

 34 service{
 35         name:pacemaker
 36         ver:0
 37 }

[root@server1 corosync]# scp corosync.conf 172.25.92.9:/etc/corosync/

[root@server1 corosync]# /etc/init.d/corosync start
Starting Corosync Cluster Engine (corosync):               [  OK  ]
[root@server1 corosync]# tail -f /var/log/messages
#如果日志中有很多error,可能是因为多播地址或者端口冲突

#健康检测:
[root@server1 ~]# crm_verify -LV  发现没有fence设备报错

#安装crm管理工具:
[root@server1 ~]# yum install crmsh-1.2.6-0.rc2.2.1.x86_64.rpm pssh-2.3.1-2.1.x86_64.rpm


#配置禁掉fence功能
在主机上:/etc/fence_virtd stop
[root@server1 ~]# crm
crm(live)# configure 
crm(live)configure# property stonith-enabled=false
[root@server1 ~]# crm_verify -LV    #不报错

#关闭集群对节点数量的检查,集群默认最少量台主机,如果只是一台主机不能接管资源
crm(live)configure# property no-quorum-policy=ignore
crm(live)configure# commit

#添加资源,vip
crm(live)configure# primitive vip ocf:heartbeat:IPaddr2 params ip=172.25.92.100 cidr_netmask=24 op monitor interval=20s        #添加vip,并设置20s对资源监察一次,监控端可以发现vip资源添加上
crm(live)configure# commit

测试:在主机上访问:curl 172.25.92.100可以看见server3上的html页面。关掉其中一台corosnsc,vip会上到另一台主机上。

#添加资源haproxy:
crm(live)configure# primitive haproxy lsb:haproxy op monitor interval=30s
crm(live)configure# commit 

#添加haproxy后可以看出来vip和haproxy不再一台主机上,资源飘移:
#解决办法:建立资源组就可以解决
crm(live)configure# group westos vip haproxy
crm(live)configure# commit 

#添加资源fence:
添加fence之前首先开启主机上:systemctl start fence_virtd
yum install -y fence-virt.x86_64 fence-agents.x86_64 #两台主机上都做(server1和server9) ``!!!!! ``
crm(live)configure# property stonith-enabled=true  #开启fence功能
crm(live)configure# commit

[root@server1 ~]# stonith_admin -I   #查看主机支持fence的代理类型。本次使用fence_xvm
[root@server1 ~]# stonith_admin -M -a fence_xvm

crm(live)configure# primitive vmfence stonith:fence_xvm params  pcmk_host_map="server1:server1;server9:server9" op monitor interval=1min    #添加fence资源,并做好集群节点名和真实server的名字映射

#测试fence功能:
首先设置:corsync在两台主机上可其自启动:chkconfig corosync on
reboot(重启动)其中一台主机,等主机开启后会自动加到集群中!

#对集群 资源 的管理:
crm(live)resource# show        #显示资源种类,此处时只添加了一个资源vip,所以显示一个 
 vip    (ocf::heartbeat:IPaddr2):   Started #开启vip资源
crm(live)resource# stop vip
crm(live)resource# show
 vip    (ocf::heartbeat:IPaddr2):   Stopped  #停掉vip资源

#对集群 节点 的管理:
[root@server1 ~]# crm
crm(live)# node 
crm(live)node# standby     #停掉server1节点
crm(live)node# online      #开启sesrver1节点

server9:和server1是同步的,但此处作为监控

yum install -y pacemaker corosync
/etc/init.d/corosync start
#安装管理工具:
[root@server9 ~]# yum install pssh-2.3.1-2.1.x86_64.rpm crmsh-1.2.6-0.rc2.2.1.x86_64.rpm 
#监控集群:
[root@server9 ~]# crm_mon

haproxy TCP源端口耗尽问题

此文基本是翻译aloha的一篇文档,本人实际使用情况遇到的问题类似,但不是MySQL。

[2017.01.12 增补] 1.7版的haproxy开启了IP_BIND_ADDRESS_NO_PORT支持 ,即可以复用source port,这样可以从更基础的内核层面解决这个问题,唯一不足是需要将内核升级到4.2以上版本才可以。
参考:
http://www.haproxy.org/download/1.7/src/CHANGELOG
https://kernelnewbies.org/Linux_4.2#head-8ccffc90738ffcb0c20caa96bae6799694b8ba3a

环境描述

小公司,一个比较繁忙的PHP/MySQL构建的站点。
前端使用haproxy做负载均衡,后端web server连接MySQL数据库。
MySQL做了主从复制,前端PHP代码做了读写分离。
MySQL Master负责写入请求和一小部分读请求,MySQL Slave负责响应读请求。
另一个haproxy作为MySQL的反向代理。

拓扑图

未分类

问题描述

在请求很少的时候,工作得非常好。但当MySQL上的请求压力增大(2~3K次/秒)的时候,haproxy的本地端口耗尽。日志中报大量health check SOCKERR错误。

原因分析

haproxy作为反向代理,会使用自己的IP地址作为源地址连接后端的MySQL服务器。
根据TCP协议,无论任何类型操作系统都只能拥有64K个左右的源TCP端口,用于向外发起TCP连接。
一旦”srcIP:port => dstIP:port”建立,这个源端口将不能被重用于其它连接。
当前的MySQL Client Lib关闭连接时的操作序列如下:

Mysql Client ==> "QUIT" sequence ==> Mysql Server 
Mysql Client ==> FIN ==> MySQL Server 
Mysql Client <== FIN ACK <== MySQL Server 
Mysql Client ==> ACK ==> MySQL Server

这时候MySQL Client会进入2MSL状态,时间2分钟。
那么什么是2MSL状态呢?请看下图,这是关于TCP关闭连接时的握手序列:

未分类

上边TCP状态图中有一个TIME_WAIT状态,就是所谓的2MSL状态。
MSL就是maximum segment lifetime(最大分节生命期),这是一个IP数据包能在互联网上生存的最长时间,超过这个时间将在网络中消失。
MSL在RFC 1122上建议是2分钟,而源自berkeley的TCP实现传统上使用30秒。
因而,TIME_WAIT状态一般维持在1-4分钟。
该状态是为了可靠地实现TCP全双工连接的终止,保证在tcp客户端发给tcp服务端的最后一个ACK能顺利到达。
若没有TIME_WAIT状态,tcp客户端将直接进入CLOSED状态。
如果tcp客户端直接进入CLOSED状态,那么由于IP协议的不可靠性或者是其它网络原因,导致tcp服务端没有收到tcp客户端最后回复的ACK。那么tcp服务端就会在超时之后继续发送FIN,此时由于tcp客户端已经CLOSED了,就找不到与重发的FIN对应的连接,最后tcp服务端就会收到 RST而不是ACK,tcp服务端就会以为是连接错误把问题报告给高层协议。
这样的情况虽然不会造成数据丢失,但是却导致TCP协议不符合可靠连接的要求。
所以,tcp客户端不是直接进入CLOSED状态,而是要保持TIME_WAIT,当再次收到FIN的时候,能够保证对方收到ACK,最后正确的关闭连接。

这里有2点需要强调一下:

1、对于tcp请求来说,tcp的客户端服务端概念和http的不同,请求双方,哪边关闭请求,哪边就是tcp客户端,另一边就为服务端。请不要与MySQL Client和MySQL Server混淆起来。
2、tcp的一个链接由4个值确定,源ip、源端口、目标ip、目标地址。

参考:http://omnitraining.net/networking-101/98-networking-101-understanding-tcp-part-2
“There is no way for the person who sent the first FIN to get an ACK back for that last ACK. You might want to reread that now. The person that initially closed the connection enters the TIME_WAIT state; in case the other person didn’t really get the ACK and thinks the connection is still open. Typically, this lasts one to two minutes.”

根据上述的论述,如果一个源端口在2分钟内不能再次使用,则超过534个/秒的MySQL Client请求将会耗尽其本地TCP源端口。
64000 (可用端口) / 120 (2分钟,即120秒) = 533.333.

因为haproxy作为反向代理,会将所有MySQL请求转发给MySQL Server,因此haproxy会比MySQL Client更快的耗尽本地TCP源端口!!

但是如果MySQL Client和MySQL Server在同一台主机上,使用looback接口通信,则MySQL关闭序列是一个相对”干净”的序列:

Mysql Client ==> "QUIT" sequence ==> Mysql Server
Mysql Client <== FIN <== MySQL Server 
Mysql Client ==> FIN ACK ==> MySQL Server 
Mysql Client <== ACK <== MySQL Server

但在非loopback接口上则不是!因此如果要解决这个问题,需要MySQL的开发者修改他们的代码……
那么是不是完全没有办法呢?也不是,请向下看。

解决方案

1、增加本地端口范围
对于单一的dstIP:port,可用的源端口默认是28K左右,可以用如下命令查看当前值:

[haproxy ~]# sysctl net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 32768 61000

增加到64K个源端口

[haproxy ~]# vi /etc/sysctl.conf
net.ipv4.ip_local_port_range = 1025 65000

2、允许处于TIME_WAIT状态的源端口重用

[haproxy ~]# vi /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

3、使用多个IP连接单一dstIP:port,并让haproxy来管理源端口
配置示例:

....
server mysql1     10.0.0.1:3306 check source 10.0.0.100:1025-65000
server mysql1_bis 10.0.0.1:3306 check source 10.0.0.101:1025-65000
....

经过测试,如果不让haproxy管理源端口,则4个源IP地址最多管理不超过80K个TIME_WAIT连接。
但是haproxy管理源端口可以达到170K+个TIME_WAIT连接!!!

4、使用memcached和MySQL persistant connections

参考文档:
http://blog.exceliance.fr/2012/12/12/haproxy-high-mysql-request-rate-and-tcp-source-port-exhaustion/
http://go12345.iteye.com/blog/1798119
http://ganquan.org/blog/2009/09/tcp协议的time_wait状态详解/
http://kerry.blog.51cto.com/172631/105233/

HAProxy概念、配置、生产实例

HAProxy实验环境准备

node1:扮演调度器(安装HAProxy),node2:扮演后台web服务器节点1(安装nginx),node3:扮演后台web服务器节点2(安装nginx)。有关虚拟机安装后常见操作请看上一篇文章。

先来一波,让HAProxy运行起来

先把需要的软件安装好:

node1 ]# yum install -y haproxy
node2 ]# yum install -y nginx
node3 ]# yum install -y nginx

把node2、node3的nginx服务启动起来,添加网页文件(后面可能会写一篇关于nginx的文章)。
对于node1,修改HAP的配置文件(生产环境中,修改配置文件前要先做好备份):

node1 ]# vim /etc/haproxy/haproxy.cfg
保留global段、defaults段,其他配置信息都删掉。添加以下配置:
listen NginxServers
        bind *:80
        balance static-rr
        server N1 node2:80
        server N2 node3:80
启动HAP服务:node1 ]# systemctl start haproxy.service

打开浏览器,访问node1节点80端口,刷新网页,可以看到HAP已经能够正常工作!并把HTTP请求按照轮询的方式调度给node2和node3节点的nginx服务。

未分类

未分类

HAProxy介绍

HAProxy,High Available Proxy,即高可用的代理服务器。要注意的是,这里的高可用不是指HAP服务自身实现了高可用,而是指HAP原生自带对后端服务器的健康状态检查机制,若发现某个BackEnd Server不可用,服务请求就不会再发往此后端节点。
HAP是一种软件实现的负载均衡器,因此它工作为用户空间的一个进程,基于套接字与客户端,后端主机进行通信。基于此,HAP能够很好地支持对HTTP请求的七层调度,对HTTP请求实现诸如“动静分离”,“HTTP方法分离”等。另外,HAP支持通过模拟方式实现四层调度,四层调度性能应该稍差。
总的来说,HAP是目前最主流的七层调度器实现方案之一,具有较好的性能以及配置多样性。

HAP配置详解

HAP将配置文件分为两大段。

  • Global段:用来定义进程安全相关配置,性能参数调整,Debug等服务相关的配置。

  • Proxy段:用来定义与调度的具体实现方式,Proxy段具体包括

    • listen段:listen可以直接确定一种调度工作方式
    • frontend段:定义与客户端通信的工作方式
    • backend段:定义与后端主机通信的工作方式
    • defaults段:定义listen,frontend,backend中某些变量的默认值

global:全局配置段常用变量

进程及安全配置相关参数:
       chroot  /var/lib/haproxy:禁锢根,haproxy进程以此目录作为根目录,防止haproxy进程被劫持而设定的安全性配置
       user  haproxy: 运行haproxy进程的用户和组
       group haproxy:
       daemon:表示haproxy运行于后台守护进程,而非前台(调试模式)
       nbproc <number>:指明要启动的haproxy进程数量; haproxy默认工作于基于事件驱动的单进程模型(也可以指明为启动多进程,官方并不建议)
       ulimit-n <number>:每个haproxy进程能够打开的最大文件数:此参数非常重要,因为每一个连接都需要打开一个socket file,因此该值至少大于进程数 * 每个进程接受的最大连接数。haproxy能够根据运行情况自行调整该值,一般不需要定义
       log:定义全局的syslog服务器,用于将haproxy产生的日志发往并存储
             log <address> <facility> [level]

好像现在HAP默认关闭了日志记录,要启用还挺麻烦,大家可以参考这篇文章作者的启用方式,测试有效!HAProxy启用日志

     性能调整相关参数
       maxconn 4000:单个haproxy进程所能接受的最大并发连接数
       maxpipes:使用pipe机制实现内核级tcp报文重组;每进程能够使用的最大pipe数量;haproxy能够自动调整
       spread-checks <0..50>:百分比数字,用于打散健康状态监测的时间点。例如每隔60秒对后端100台主机进行健康状态检查,此值设定为20表示,某台主机进行完一次检查后,下一次的检查时间可能是(48s,72s)内的任何一个时间,这样就打散了每台主机的检查时间,从而减轻了由于health-check带来的性能消耗
      Debug相关参数
        debug:详细输出日志信息(调试模式时)
        quiet:简化日志的输出信息

下面介绍Proxy段中的常用变量:这些变量可用于listen,frontend,backend中的一个或多个

1、bind:可用在listen,frontend;用于指明haproxy服务监听的套接字地址
   # bind <address>:<port_range>,....[param*]

e.g.    bind *:80 ssl, 192.168.1.7/24:8080 

表示haproxy监听于任意ipv4地址的80端口(外部访问),以及192.168.1.7:8080这一地址(内部访问),同时,并且受理外部请求时必须是https连接。      


2、balance:可用在listen,backend,default;用于指明对后端server使用的调度算法
     # balance <algo> [params]
              <algo>: 表示调度算法,常用的调度算法如下:
                roundrobin  [加权]轮询
                 动态算法,支持权重的运行时调整以及慢启动机制;最多4095个后端主机
                 慢启动:若共6000个连接,3台后端服务器,权重均相同,则每台处理2000个连接。此时新增一台服务器,那么应该每台处理1500个连接,所以大量的新连接都会给新增的那台,极易造成压力过大,慢启动则避免了这点
                static-rr    [加权]轮询
                 静态算法:不支持权重的运行时调整以及慢启动机制;后端主机无数量限制

                leastconn   最少连接
                推荐使用在较长时间会话场景中,如LDAP,MYSQL协议

                first    依次处理请求
                  每台后端主机可定义自己的maxconn。first算法根据maxconn的从大到小为后端主机排序,然后每次都将连接请求发给maxconn最大的那台主机,直到达到它的maxconn,才调度给下一台sever。
                  first算法的好处是能够节约虚拟机资源(backendserver一般是虚拟机实例),按需决定启动多少台虚拟机,坏处是配置麻烦,单台虚拟机处理太多连接压力过大。

               source  源地址hash ---> 会话绑定
               uri     目标地址hash ---> 提高缓存命中率

                    采用哈希调度算法时,NEW连接首次被调度至哪里可用hash-type命令由两种方式指定:
                    #  hash-type <method>
                              map-based  取模法
                              consistent    一致性哈希

                hdr(<name>)  
                      对于每个http请求,此处name指定的http报文首部会被取出做hash计算。然后再有相同的请求时,调度给同一台主机。source和uri是它最常用的hash调度子类
            e.g.   对于某个站点,可能由多个域名,如jd.com,www.jd.com,对于请求报文中不同Host,都始终调度给同一台backend_server       
                              balance  hdr(Host)
                              hash-type  map-based


3、log:用在default,frontend,backend,listen;定义日志的记录位置,做多定义两个位置。
        # log global || #  log <address> <facility> [level] || #  no log
        分别表示使用全局配置中的log记录位置或使用自定义的日志记录位置或不记录日志


4、capture request header;用在listen,frontend;用于添加指定请求报文首部信息记录于日志中
    # capture request header <name> len <length>
    e.g.  capture request header User-Agent len 10


5、capture response header ;用在listen,frontend;用于添加指定响应报文首部信息记录于日志中
    # capture response header <name> len <length>
e.g.  capture response header Cache-Control len 5


6、compression;用在listen,frontend,backend;用于压缩报文中的body部分
    # compression algo <algorithm>
    # compression type <mime type>
        支持的压缩algo:gzip,deflate
        mime type:通常只压缩文本类信息
e.g.   compression algo gzip 
         compression type  text/html
注意:compression用在frontend中表示压缩与客户端通信报文中的body,用在backend中则表示压缩与后端主机通信过程中报文的body


7、server:用于listen,backend;用来定义一个后端主机
    #  server <name> <addr:port> [params*]
        <name>:HAProxy中服务器的唯一标识,必给
        <addr:port>:后端主机监听的ip地址及端口
        [params*]:定义一个主机时同时可指定的可选参数
                backup:设定为备用服务器,仅在LB中其他服务器均不可用时才接受请求。类似于nginx-upstream定义主机时的down,用于维护时下线主机
                check:对后端主机作基于tcp端口的四层健康状态检测;check后可跟辅助参数,也可仅适用默认值
                            inter<delay>:每隔多久做一次检测
                            fall<count>:连续多少次失败从LB中移除该主机
                            rise<count>:连续多少次成功从LB中添加该主机
                maxconn:指定该服务器支持的最大连接数
                maxqueue:指定该服务器支持的最大等待队列长度
                cookie <name>:本台server的cookie信息,可任意指定
                redir <prefix>:将发往此服务器的所有GET,HEAD请求重定向至指定地址
                weight <weight>:指定权重


8、httpchk:用于listen,backend;基于7层http协议对后端主机进行状态检测
   # option httpchk  <uri>
e.g.   option httpchk  /login.html    


9、cookie:用于listen,backend;设定基于cookie的会话绑定       
    # cookie <name> [ insert | prefix | rewrite ] [params*]
            <name>:cookie标签的名字
            insert:插入某主机的cookie信息
            prefix:在cookie前添加信息
            rewrite:重写cookie
e.g.   cookie  WEBNODES insert  indirect nocache
         server node1 172.16.100.67:8100 check cookie node1
         server node1 172.16.100.67:8100 check cookie node1  
            随后,在HTTP请求报文中可以看到添加的cookie信息,并且一段时间内来自同一cip的请求被调度至了同一台server


10、mode:用在default,frontend,backend,listen;指明haproxy的工作模式
    # mode {tcp | http}
       http:后端LB集群为web server时,应设定mode为http模式,此时支持各种高级分析功能
       tcp:当后端LB集群为mysq等非基于http协议通信的服务时,应使haproxy工作于tcp模式,此时可调度mysql,ldap,ssh,ssl等协议的通信报文


11、forwardfor:在后端web server的日志文件中记录下CIP而非DIP()
 e.g.  option forwardfor  except  127.0.0.1/8
        同时修改后端httpd配置文件中的Logformat中 %h为  %{X-Forwarded-For}i


12、option http-keep-alive
        option http-server-close
前者表示启用与client端通信时的长连接功能,启用此功能时,一般需要同时启用后者,表示允许HAProxy关闭非活动状态的长连接。


13、rspadd <search>    haproxy在给client的响应报文中添加某自定义header;用于listen,backend中
        # rspdel <search>     haproxy在给client的响应报文中查找某hearder并删除
        # rspidel <search>    haproxy在给client的响应报文中基于正则表达式查找某hearder并删除
 e.g.   在响应报文中,一般我们不想让客户端知道后端real server的信息,可用以下指令完成
      rspidel  ^Server:.*     

若要实现复杂的调度能够,如“动静分离”,则需要定于ACL相关变量:

 1、 acl:用在frontend中,定义一条acl匹配规则 
# acl <aclname> <criterion> [flags] [operator] <value> ...
           criterion:acl匹配检查规则
                四层
                    dst IP  
                    dst_port PORT
                    src  IP
                    src_port  PORT
                七层
                    method <http_method>:指明http报文中的请求方法

                    path:URI精确匹配
                    path_beg:URI开头匹配
                    path_end:URI结尾匹配
                    path_reg:URI正则表达式匹配

                    url:URL精确匹配
                    url_beg:URL开头匹配
                    url_end:URL结尾匹配
                    url_end:URL正则表达式匹配

                    hdr <name><value>:请求报文中某个header值的精确匹配
                    hdr_beg <name><value>:请求报文中某个header值的开头匹配
                    hdr_end <name><value>:请求报文中某个header值的结尾匹配

          flags:   -i   表示匹配检查时忽略字符大小写

          value:匹配检查的对象


2、use_backend:用于frontend中,表示当满足某个acl时,调用指定的backend <name>
# use_backend <backend> [if | unless <acl_name>]



3、default_backend:用于frontend中,指明默认将请求调度给哪个backend <name>
# deault_backend <backend>



4、block:用于frontend中,符合acl规则时,阻止访问请求
# block if | unless <acl_name>

HAP生产配置环境案例

1、启用HAProxy内置管理页面

  listen stats  *:9001         定义访问管理页面的IP:PORT
      stats  enable                         启用此功能
      stats  uri  /haproxyadmin          定义访问的URI
      stats  realm  "ADMIN AREA"             页面提示信息,要求用户登录后访问
      stats  auth  admin:123456abc         设定登录用户的账号密码
      stats  admin  if TRUE             如果登录成功,在此页面开启管理接口权限(默认只能查看运行状态统计信息)

2、HAProxy实现模拟实现四层调度

  listen MySQLsrvs
      bind *:20002
      balance leastconn          使用最少连接调度算法
      mode tcp                   定义为四层调度
      server sqlnode1 172.16.100.67:3306 check
      server sqlnode2 172.16.100.68:3306 check

3、配置一个能够实现动静分离的调度服务器:

frontend dirctor
    bind *:80,*:8080
    acl picreq path_end -i .jpg .jepg .bmp
    acl phpreq path_end -i .php
    acl putreq method put
    acl stop src 222.222.222.0/24

    use_backend picsrvs if picreq
    use_backend phpsrvs if phpreq
    use_backend putnode if putreq
    default_backend stasrvs
    block if stop

backend picsrvs
    balance roundrobin
    server picnode1 172.16.100.67:8100 check weight 1 maxconn 2000
    server picnode2 172.16.100.77:8100 check weight 2 maxconn 2000

backend phpsrvs
    balance roundrobin
    cookie PHP insert indirect nocache
    server phpnode1 172.16.100.68:8100 check maxconn 300 cookie phpnode1
    server phpnode2 172.16.100.78:8100 check maxconn 300 cookie phpnode2

backend putnode
    balance static-rr
    server node 172.16.100.69:8100 check

backend stasrvs
    balance roundrobin
    server httpnode1 172.16.100.70:8100 check maxconn 2000 weight 1
    server httpnode2 172.16.100.80:8100 check maxconn 2000 weight 2

Ubuntu 安装java8(jdk8)和java7(jdk7)并灵活切换

前言

本机装的是 jdk7 ,无奈最近看的源码不少都已经拥抱 jdk8 了。便于调试,安装了新的 java 版本。

安装 jdk

这里简单说明下 Ubuntu 下 jdk8 的安装过程,jdk7 的类似,不再赘述。

下载安装包: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html ,选择 jdk-8u162-linux-x64.tar.gz。

新建目录并解压到该目录

sudo mkdir /usr/lib/java
sudo tar zxvf ./jdk-8u162-linux-x64.tar.gz -C /usr/lib/java
sudo mv /usr/lib/java/jdk1.8.0_162/ /usr/lib/java/jdk8

打开配置文件, sudo gedit /etc/profile, 在文件中加入以下内容

export JAVA_HOME=/usr/lib/java/jdk8
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH

将新安装的 jdk 加入到选项里

sudo update-alternatives --install /usr/bin/java java /usr/lib/java/jdk8/bin/java 300
sudo update-alternatives --install /usr/bin/javac javac /usr/lib/java/jdk8/bin/javac 300

通过 sudo update-alternatives –config java 指令,选择相应的jdk即可!

$ sudo update-alternatives --config java       
There are 3 choices for the alternative java (providing /usr/bin/java).

  Selection    Path                                            Priority   Status
------------------------------------------------------------
  0            /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java   1071      auto mode
* 1            /usr/lib/java/jdk7/bin/java                      300       manual mode
  2            /usr/lib/java/jdk8/bin/java                      300       manual mode
  3            /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java   1071      manual mode

Press enter to keep the current choice[*], or type selection number: 2
update-alternatives: using /usr/lib/java/jdk8/bin/java to provide /usr/bin/java (java) in manual mode

然后在命令行里查看 jdk 的版本

$ java -version
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)

切换 jdk 版本

修改 $PATH 中的java路径,然后通过 sudo update-alternatives –config java 指令切换版本即可!

Ubuntu搭建ghost博客 V1.20

官方推荐以下环境:

  • Ubuntu 16.04
  • MySQL
  • NGINX (minimum of 1.9.5 for SSL)
  • Systemd
  • Node v6 installed via NodeSource
  • 至少1GB内存 (可用)
  • 可运行Ghost的非root用户

增加运行Ghost用户

adduser <user>

(为自定义的用户名称,需改,下同)

usermod -aG sudo <user>

为新增用户添加root权限

su - <user>

切换到新增用户

升级Packages

sudo apt-get update

升级package lists

sudo apt-get upgrade

升级installed packages

安装Mysql&Nginx

sudo apt-get install nginx

安装nginx

sudo ufw allow 'Nginx Full'

打开HTTP/HTTPS防火墙

sudo apt-get install mysql-server

安装mysql数据库(root密码不要设为空)

安装Node.js

curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash

安装6版本以上的Node.js

sudo apt-get install -y nodejs

运行安装命令

安装Ghost-CLI

sudo npm i -g ghost-cli

用CLI安装Ghost博客

sudo mkdir -p /var/www/ghost

新建一个ghost博客的目录(可改)

sudo chown [user]:[user] /var/www/ghost

给新增的用户全部新建的目录的权限

cd /var/www/ghost

进入目录

ghost install

安装ghost博客

后面会提示你输入ghost地址,只需要把域名解析到服务器地址并输入博客地址就行,一键安装包会帮你配置Nginx,并且支持一键申请ssl。

使用PM2让你的ghost博客保持运行

cd /var/www/ghost  
npm install pm2 -g # 安装PM2  
NODE_ENV=production pm2 ghost start --name "ghost"  
pm2 startup ubuntu  
pm2 save 

如果是centos请把代码中的ubuntu改为centos,debian也是如此。
因为GFW的强大,在上一步直接使用npm安装依赖的时候可能出现无法安装的情况,这时候可以使用以下代码:

npm install -g cnpm --registry=https://registry.npm.taobao.org  
cnpm install pm2 -g  
NODE_ENV=production pm2 start index.js --name "ghost"  
pm2 startup   ubuntu
pm2 save  

这样一来,我们的Ghost博客就可以保持运行啦,你可以使用以下指令来控制Ghost博客:

pm2 start/stop/restart ghost

Ubuntu下Python设置pip使用国内源站

在用户目录下建立.pip/pip.conf文件

cd ~/ && mkdir .pip
cd .pip && nano pip.conf

写入以下配置并保存即可

[global]
index-url = https://pypi.douban.com/simple/

当然,还可以选择使用清华,阿里等源站

清华:https://pypi.tuna.tsinghua.edu.cn/simple
阿里: https://mirrors.aliyun.com/pypi/simple

未分类

解决 Ubuntu 下 ssh 服务器中文显示乱码

在 Ubuntu 16.10 下使用终端 ssh 登录远程服务器,然后使用服务器上的 VIM 打开代码文件,发现文件中的中文都是乱码。而使用 Mac 的自带终端进行同样的操作,看到的中文显示就是正常的。遂怀疑 Ubuntu 本地的配置有问题。

问题的原因是,本地的 locale 与服务器上的 locale 不匹配。参考链接里提供了四种解决方案,而我觉得 Stop forwarding locale from the client 这种解决方案最简单。

即,修改 Ubuntu 本地的 /etc/ssh/ssh_config 文件,注释掉

SendEnv LANG LC_*

这一行。然后重新 ssh 服务器,会发现中文已经可以正常显示了。

CentOS 6.9上inotify-tools 安装及使用方法

Linux内核从2.6.13开始,引入了inotify机制。通过intofity机制,能够对文件系统的变化进行监控,如对文件进行创建、删除、修改等操作,可以及时通知应用程序进行相关事件的处理。这种响应处理机制,避免了频繁的文件轮询任务,提高了任务的处理效率。

一、检查系统内核版本

[root@localhost tan]# uname -r
2.6.32-696.el6.x86_64

二、检查系统是否支持inotify

[root@localhost tan]# ls -lsart /proc/sys/fs/inotify  
total 0
0 dr-xr-xr-x 0 root root 0 Jan 17 08:47 ..
0 dr-xr-xr-x 0 root root 0 Jan 17 08:53 .
0 -rw-r--r-- 1 root root 0 Jan 19 13:33 max_user_watches
0 -rw-r--r-- 1 root root 0 Jan 19 13:33 max_queued_events
0 -rw-r--r-- 1 root root 0 Jan 19 13:40 max_user_instances
[root@localhost tan]#

如果出现上面结果说明系统支持inotify。

三、下载安装(下载有点慢)

[root@localhost tan]#wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz  

[root@localhost tan]# tar -zvxf inotify-tools-3.14.tar.gz  
[root@localhost tan]# cd inotify-tools-3.14  

[root@localhost inotify-tools-3.14]# ./configure --prefix=/usr/local/inotify  
[root@localhost inotify-tools-3.14]# make  
[root@localhost inotify-tools-3.14]# make install

四、查看inotify默认参数

[root@localhost bin]# sysctl -a | grep max_queued_events  
fs.inotify.max_queued_events = 16384  

[root@localhost bin]# sysctl -a | grep max_user_watches  
fs.inotify.max_user_watches = 8192  
fs.epoll.max_user_watches = 798863  

[root@localhost bin]# sysctl -a | grep max_user_instances  
fs.inotify.max_user_instances = 128

五、修改inotify参数

1、命令修改

[root@localhost bin]# sysctl -w fs.inotify.max_user_instances=130  
fs.inotify.max_user_instances = 130

2、文件修改

[root@localhost]# vi /etc/sysctl.conf  
#添加如下代码  
fs.inotify.max_user_instances=130

3、参数说明

  • max_user_instances:每个用户创建inotify实例最大值
  • max_queued_events:inotify队列最大长度,如果值太小,会出现错误,导致监控文件不准确
  • max_user_watches:要知道同步的文件包含的目录数,可以用:
    [root@localhost]# find /home/rain -type d|wc -l 统计,必须保证参数值大于统计结果(/home/tan/uploadFile/为同步文件目录)。

六、创建实时监控脚本 (file 里面放的需要监听的目录)

[root@localhost shell]# vi inotify.sh
/usr/local/inotify/bin/inotifywait -mrq -e modify,create,move,delete --fromfile '/root/shell/file' --timefmt '%y-%m-%d %H:%M' --format '%T %w%f %e' --outfile '/home/tan/inotify.log'
[root@localhost shell]# vi file 

/home/tan
@/home/tan/uploadFile

inotifywait常用参数:

  • –timefmt 时间格式
  • %y年 %m月 %d日 %H小时 %M分钟
  • –format 输出格式
  • %T时间 %w路径 %f文件名 %e状态
  • -m 始终保持监听状态,默认触发事件即退出。
  • -r 递归查询目录
  • -q 打印出监控事件
  • -e 定义监控的事件,可用参数:
  • open 打开文件
  • access 访问文件
  • modify 修改文件
  • delete 删除文件
  • create 新建文件
  • attrb 属性变更
事件  描述

access  访问,读取文件。
modify  修改,文件内容被修改。
attrib  属性,文件元数据被修改。
move    移动,对文件进行移动操作。
create  创建,生成新文件
open    打开,对文件进行打开操作。
close   关闭,对文件进行关闭操作。
delete  删除,文件被删除。

七:实例操作

1、首先启动监听脚本,权限问题的话先:chmod 755 inotify.sh

[root@localhost shell]# ./inotify.sh

我在监听的目录中上传文件,没截图,自己想象吧

[root@localhost tan]# cat inotify.log 
18-01-19 15:07 /home/tan/uploadfile/test//ssh.txt CREATE
18-01-19 15:13 /home/tan/uploadfile/test/QQ20180119143826.png CREATE

这里可以看到打印的日志了。

八、附

1、inotifywait

使用方法和参数说明: 使用命令help就行

[root@localhost bin]# ./inotifywait -h
inotifywait 3.14
Wait for a particular event on a file or set of files.
Usage: inotifywait [ options ] file1 [ file2 ] [ file3 ] [ ... ]
Options:
        -h|--help       Show this help text.
        @<file>         Exclude the specified file from being watched.
        --exclude <pattern>
                        Exclude all events on files matching the
                        extended regular expression <pattern>.
        --excludei <pattern>
                        Like --exclude but case insensitive.
        -m|--monitor    Keep listening for events forever.  Without
                        this option, inotifywait will exit after one
                        event is received.
        -d|--daemon     Same as --monitor, except run in the background
                        logging events to a file specified by --outfile.
                        Implies --syslog.
        -r|--recursive  Watch directories recursively.
        --fromfile <file>
                        Read files to watch from <file> or `-' for stdin.
        -o|--outfile <file>
                        Print events to <file> rather than stdout.
        -s|--syslog     Send errors to syslog rather than stderr.
        -q|--quiet      Print less (only print events).
        -qq             Print nothing (not even events).
        --format <fmt>  Print using a specified printf-like format
                        string; read the man page for more details.
        --timefmt <fmt> strftime-compatible format string for use with
                        %T in --format string.
        -c|--csv        Print events in CSV format.
        -t|--timeout <seconds>
                        When listening for a single event, time out after
                        waiting for an event for <seconds> seconds.
                        If <seconds> is 0, inotifywait will never time out.
        -e|--event <event1> [ -e|--event <event2> ... ]
                Listen for specific event(s).  If omitted, all events are 
                listened for.

Exit status:
        0  -  An event you asked to watch for was received.
        1  -  An event you did not ask to watch for was received
              (usually delete_self or unmount), or some error occurred.
        2  -  The --timeout option was given and no events occurred
              in the specified interval of time.

Events:
        access          file or directory contents were read
        modify          file or directory contents were written
        attrib          file or directory attributes changed
        close_write     file or directory closed, after being opened in
                        writeable mode
        close_nowrite   file or directory closed, after being opened in
                        read-only mode
        close           file or directory closed, regardless of read/write mode
        open            file or directory opened
        moved_to        file or directory moved to watched directory
        moved_from      file or directory moved from watched directory
        move            file or directory moved to or from watched directory
        create          file or directory created within watched directory
        delete          file or directory deleted within watched directory
        delete_self     file or directory was deleted
        unmount         file system containing file or directory unmounted

2、inotifywatch

使用方法和参数说明:

[root@localhost bin]# ./inotifywatch -h
inotifywatch 3.14
Gather filesystem usage statistics using inotify.
Usage: inotifywatch [ options ] file1 [ file2 ] [ ... ]
Options:
        -h|--help       Show this help text.
        -v|--verbose    Be verbose.
        @<file>         Exclude the specified file from being watched.
        --fromfile <file>
                Read files to watch from <file> or `-' for stdin.
        --exclude <pattern>
                Exclude all events on files matching the extended regular
                expression <pattern>.
        --excludei <pattern>
                Like --exclude but case insensitive.
        -z|--zero
                In the final table of results, output rows and columns even
                if they consist only of zeros (the default is to not output
                these rows and columns).
        -r|--recursive  Watch directories recursively.
        -t|--timeout <seconds>
                Listen only for specified amount of time in seconds; if
                omitted or 0, inotifywatch will execute until receiving an
                interrupt signal.
        -e|--event <event1> [ -e|--event <event2> ... ]
                Listen for specific event(s).  If omitted, all events are 
                listened for.
        -a|--ascending <event>
                Sort ascending by a particular event, or `total'.
        -d|--descending <event>
                Sort descending by a particular event, or `total'.

Exit status:
        0  -  Exited normally.
        1  -  Some error occurred.

Events:
        access          file or directory contents were read
        modify          file or directory contents were written
        attrib          file or directory attributes changed
        close_write     file or directory closed, after being opened in
                        writeable mode
        close_nowrite   file or directory closed, after being opened in
                        read-only mode
        close           file or directory closed, regardless of read/write mode
        open            file or directory opened
        moved_to        file or directory moved to watched directory
        moved_from      file or directory moved from watched directory
        move            file or directory moved to or from watched directory
        create          file or directory created within watched directory
        delete          file or directory deleted within watched directory
        delete_self     file or directory was deleted
        unmount         file system containing file or directory unmounted

在 RHEL/CentOS 系统上使用 YUM history 命令回滚升级操作

为服务器打补丁是 Linux 系统管理员的一项重要任务,为的是让系统更加稳定,性能更加优化。厂商经常会发布一些安全/高危的补丁包,相关软件需要升级以防范潜在的安全风险。

Yum (Yellowdog Update Modified) 是 CentOS 和 RedHat 系统上用的 RPM 包管理工具,yum history 命令允许系统管理员将系统回滚到上一个状态,但由于某些限制,回滚不是在所有情况下都能成功,有时 yum 命令可能什么都不做,有时可能会删掉一些其他的包。

我建议你在升级之前还是要做一个完整的系统备份,而 yum history 并不能用来替代系统备份的。系统备份能让你将系统还原到任意时候的节点状态。

某些情况下,安装的应用程序在升级了补丁之后不能正常工作或者出现一些错误(可能是由于库不兼容或者软件包升级导致的),那该怎么办呢?

与应用开发团队沟通,并找出导致库和软件包的问题所在,然后使用 yum history 命令进行回滚。

注意:

  • 它不支持回滚 selinux,selinux-policy-*,kernel,glibc (以及依赖 glibc 的包,比如 gcc)。
  • 不建议将系统降级到更低的版本(比如 CentOS 6.9 降到 CentOS 6.8),这会导致系统处于不稳定的状态
    让我们先来看看系统上有哪些包可以升级,然后挑选出一些包来做实验。
#yum update
Loaded plugins: fastestmirror, security
Setting up UpdateProcess
Loading mirror speeds from cached hostfile
epel/metalink |12 kB 00:00
* epel: mirror.csclub.uwaterloo.ca
base |3.7 kB 00:00
dockerrepo |2.9 kB 00:00
draios |2.9 kB 00:00
draios/primary_db |13 kB 00:00
epel |4.3 kB 00:00
epel/primary_db |5.9 MB 00:00
extras |3.4 kB 00:00
updates |3.4 kB 00:00
updates/primary_db |2.5 MB 00:00
ResolvingDependencies
-->Running transaction check
--->Packagegit.x86_64 0:1.7.1-8.el6 will be updated
--->Packagegit.x86_64 0:1.7.1-9.el6_9 will be an update
--->Package httpd.x86_64 0:2.2.15-60.el6.centos.4 will be updated
--->Package httpd.x86_64 0:2.2.15-60.el6.centos.5 will be an update
--->Package httpd-tools.x86_64 0:2.2.15-60.el6.centos.4 will be updated
--->Package httpd-tools.x86_64 0:2.2.15-60.el6.centos.5 will be an update
--->Package perl-Git.noarch 0:1.7.1-8.el6 will be updated
--->Package perl-Git.noarch 0:1.7.1-9.el6_9 will be an update
-->FinishedDependencyResolution
DependenciesResolved
=================================================================================================
PackageArchVersionRepositorySize
=================================================================================================
Updating:
git x86_64 1.7.1-9.el6_9 updates 4.6 M
httpd x86_64 2.2.15-60.el6.centos.5 updates 836 k
httpd-tools x86_64 2.2.15-60.el6.centos.5 updates 80 k
perl-Git noarch 1.7.1-9.el6_9 updates 29 k
TransactionSummary
=================================================================================================
Upgrade4Package(s)
Total download size:5.5 M
Isthis ok [y/N]: n

你会发现 git 包可以被升级,那我们就用它来实验吧。运行下面命令获得软件包的版本信息(当前安装的版本和可以升级的版本)。

#yumlistgit
Loaded plugins: fastestmirror, security
Setting up UpdateProcess
Loading mirror speeds from cached hostfile
* epel: mirror.csclub.uwaterloo.ca
InstalledPackages
git.x86_64 1.7.1-8.el6@base
AvailablePackages
git.x86_64 1.7.1-9.el6_9 updates

运行下面命令来将 git 从 1.7.1-8 升级到 1.7.1-9。

#yum update git
Loaded plugins: fastestmirror, presto
Setting up UpdateProcess
Loading mirror speeds from cached hostfile
* base: repos.lax.quadranet.com
* epel: Fedora.mirrors.pair.com
* extras: mirrors.seas.harvard.edu
* updates: mirror.sesp.northwestern.edu
ResolvingDependencies
-->Running transaction check
--->Packagegit.x86_64 0:1.7.1-8.el6 will be updated
-->ProcessingDependency:git=1.7.1-8.el6forpackage: perl-Git-1.7.1-8.el6.noarch
--->Packagegit.x86_64 0:1.7.1-9.el6_9 will be an update
-->Running transaction check
--->Package perl-Git.noarch 0:1.7.1-8.el6 will be updated
--->Package perl-Git.noarch 0:1.7.1-9.el6_9 will be an update
-->FinishedDependencyResolution
DependenciesResolved
=================================================================================================
PackageArchVersionRepositorySize
=================================================================================================
Updating:
git x86_64 1.7.1-9.el6_9 updates 4.6 M
Updatingfor dependencies:
perl-Git noarch 1.7.1-9.el6_9 updates 29 k
TransactionSummary
=================================================================================================
Upgrade2Package(s)
Total download size:4.6 M
Isthis ok [y/N]: y
DownloadingPackages:
Setting up and reading Presto delta metadata
Processing delta metadata
Package(s) data still to download:4.6 M
(1/2):git-1.7.1-9.el6_9.x86_64.rpm |4.6 MB 00:00
(2/2): perl-Git-1.7.1-9.el6_9.noarch.rpm |29 kB 00:00
-------------------------------------------------------------------------------------------------
Total5.8 MB/s |4.6 MB 00:00
Running rpm_check_debug
RunningTransactionTest
TransactionTestSucceeded
RunningTransaction
Updating: perl-Git-1.7.1-9.el6_9.noarch1/4
Updating:git-1.7.1-9.el6_9.x86_64 2/4
Cleanup: perl-Git-1.7.1-8.el6.noarch3/4
Cleanup:git-1.7.1-8.el6.x86_64 4/4
Verifying:git-1.7.1-9.el6_9.x86_64 1/4
Verifying: perl-Git-1.7.1-9.el6_9.noarch2/4
Verifying:git-1.7.1-8.el6.x86_64 3/4
Verifying: perl-Git-1.7.1-8.el6.noarch4/4
Updated:
git.x86_64 0:1.7.1-9.el6_9
DependencyUpdated:
perl-Git.noarch 0:1.7.1-9.el6_9
Complete!

验证升级后的 git 版本.

#yumlistgit
InstalledPackages
git.x86_64 1.7.1-9.el6_9@updates
或
# rpm -q git
git-1.7.1-9.el6_9.x86_64

现在我们成功升级这个软件包,可以对它进行回滚了。步骤如下。

使用 YUM history 命令回滚升级操作

首先,使用下面命令获取 yum 操作的 id。下面的输出很清晰地列出了所有需要的信息,例如操作 id、谁做的这个操作(用户名)、操作日期和时间、操作的动作(安装还是升级)、操作影响的包数量。

#yum history
或
#yum history list all
Loaded plugins: fastestmirror, presto
ID |Login user |Dateandtime|Action(s)|Altered
-------------------------------------------------------------------------------
13| root |2017-08-1813:30|Update|2
12| root |2017-08-1007:46|Install|1
11| root |2017-07-2817:10| E, I, U |28 EE
10| root |2017-04-2109:16| E, I, U |162 EE
9| root |2017-02-0917:09| E, I, U |20 EE
8| root |2017-02-0210:45|Install|1
7| root |2016-12-1506:48|Update|1
6| root |2016-12-1506:43|Install|1
5| root |2016-12-0210:28| E, I, U |23 EE
4| root |2016-10-2805:37| E, I, U |13 EE
3| root |2016-10-1812:53|Install|1
2| root |2016-09-3010:28| E, I, U |31 EE
1| root |2016-07-2611:40| E, I, U |160 EE

上面命令显示有两个包受到了影响,因为 git 还升级了它的依赖包 perl-Git。 运行下面命令来查看关于操作的详细信息。

#yum history info13
Loaded plugins: fastestmirror, presto
Transaction ID :13
Begintime:FriAug1813:30:522017
Begin rpmdb :420:f5c5f9184f44cf317de64d3a35199e894ad71188
Endtime:13:30:542017(2 seconds)
End rpmdb :420:d04a95c25d4526ef87598f0dcaec66d3f99b98d4
User: root
Return-Code:Success
CommandLine: update git
Transaction performed with:
Installed rpm-4.8.0-55.el6.x86_64 @base
Installedyum-3.2.29-81.el6.centos.noarch @base
Installedyum-plugin-fastestmirror-1.1.30-40.el6.noarch@base
Installedyum-presto-0.6.2-1.el6.noarch@anaconda-CentOS-201207061011.x86_64/6.3
PackagesAltered:
Updatedgit-1.7.1-8.el6.x86_64 @base
Update1.7.1-9.el6_9.x86_64 @updates
Updated perl-Git-1.7.1-8.el6.noarch@base
Update1.7.1-9.el6_9.noarch@updates
history info

运行下面命令来回滚 git 包到上一个版本。

#yum history undo 13
Loaded plugins: fastestmirror, presto
Undoing transaction 53,fromFriAug1813:30:522017
Updatedgit-1.7.1-8.el6.x86_64 @base
Update1.7.1-9.el6_9.x86_64 @updates
Updated perl-Git-1.7.1-8.el6.noarch@base
Update1.7.1-9.el6_9.noarch@updates
Loading mirror speeds from cached hostfile
* base: repos.lax.quadranet.com
* epel: fedora.mirrors.pair.com
* extras: repo1.dal.innoscale.net
* updates: mirror.vtti.vt.edu
ResolvingDependencies
-->Running transaction check
--->Packagegit.x86_64 0:1.7.1-8.el6 will be a downgrade
--->Packagegit.x86_64 0:1.7.1-9.el6_9 will be erased
--->Package perl-Git.noarch 0:1.7.1-8.el6 will be a downgrade
--->Package perl-Git.noarch 0:1.7.1-9.el6_9 will be erased
-->FinishedDependencyResolution
DependenciesResolved
=================================================================================================
PackageArchVersionRepositorySize
=================================================================================================
Downgrading:
git x86_64 1.7.1-8.el6 base 4.6 M
perl-Git noarch 1.7.1-8.el6 base 29 k
TransactionSummary
=================================================================================================
Downgrade2Package(s)
Total download size:4.6 M
Isthis ok [y/N]: y
DownloadingPackages:
Setting up and reading Presto delta metadata
Processing delta metadata
Package(s) data still to download:4.6 M
(1/2):git-1.7.1-8.el6.x86_64.rpm |4.6 MB 00:00
(2/2): perl-Git-1.7.1-8.el6.noarch.rpm |29 kB 00:00
-------------------------------------------------------------------------------------------------
Total3.4 MB/s |4.6 MB 00:01
Running rpm_check_debug
RunningTransactionTest
TransactionTestSucceeded
RunningTransaction
Installing: perl-Git-1.7.1-8.el6.noarch1/4
Installing:git-1.7.1-8.el6.x86_64 2/4
Cleanup: perl-Git-1.7.1-9.el6_9.noarch3/4
Cleanup:git-1.7.1-9.el6_9.x86_64 4/4
Verifying:git-1.7.1-8.el6.x86_64 1/4
Verifying: perl-Git-1.7.1-8.el6.noarch2/4
Verifying:git-1.7.1-9.el6_9.x86_64 3/4
Verifying: perl-Git-1.7.1-9.el6_9.noarch4/4
Removed:
git.x86_64 0:1.7.1-9.el6_9 perl-Git.noarch 0:1.7.1-9.el6_9
Installed:
git.x86_64 0:1.7.1-8.el6 perl-Git.noarch 0:1.7.1-8.el6
Complete!

回滚后,使用下面命令来检查降级包的版本。

#yumlistgit
或
# rpm -q git
git-1.7.1-8.el6.x86_64

使用YUM downgrade 命令回滚升级

此外,我们也可以使用 YUM downgrade 命令回滚升级。

#yum downgrade git-1.7.1-8.el6 perl-Git-1.7.1-8.el6
Loaded plugins: search-disabled-repos, security, ulninfo
Setting up DowngradeProcess
ResolvingDependencies
-->Running transaction check
--->Packagegit.x86_64 0:1.7.1-8.el6 will be a downgrade
--->Packagegit.x86_64 0:1.7.1-9.el6_9 will be erased
--->Package perl-Git.noarch 0:1.7.1-8.el6 will be a downgrade
--->Package perl-Git.noarch 0:1.7.1-9.el6_9 will be erased
-->FinishedDependencyResolution
DependenciesResolved
=================================================================================================
PackageArchVersionRepositorySize
=================================================================================================
Downgrading:
git x86_64 1.7.1-8.el6 base 4.6 M
perl-Git noarch 1.7.1-8.el6 base 29 k
TransactionSummary
=================================================================================================
Downgrade2Package(s)
Total download size:4.6 M
Isthis ok [y/N]: y
DownloadingPackages:
(1/2):git-1.7.1-8.el6.x86_64.rpm |4.6 MB 00:00
(2/2): perl-Git-1.7.1-8.el6.noarch.rpm |28 kB 00:00
-------------------------------------------------------------------------------------------------
Total3.7 MB/s |4.6 MB 00:01
Running rpm_check_debug
RunningTransactionTest
TransactionTestSucceeded
RunningTransaction
Installing: perl-Git-1.7.1-8.el6.noarch1/4
Installing:git-1.7.1-8.el6.x86_64 2/4
Cleanup: perl-Git-1.7.1-9.el6_9.noarch3/4
Cleanup:git-1.7.1-9.el6_9.x86_64 4/4
Verifying:git-1.7.1-8.el6.x86_64 1/4
Verifying: perl-Git-1.7.1-8.el6.noarch2/4
Verifying:git-1.7.1-9.el6_9.x86_64 3/4
Verifying: perl-Git-1.7.1-9.el6_9.noarch4/4
Removed:
git.x86_64 0:1.7.1-9.el6_9 perl-Git.noarch 0:1.7.1-9.el6_9
Installed:
git.x86_64 0:1.7.1-8.el6 perl-Git.noarch 0:1.7.1-8.el6
Complete!

注意: 你也需要降级依赖包,否则它会删掉当前版本的依赖包而不是对依赖包做降级,因为 downgrade 命令无法处理依赖关系。

至于 Fedora 用户

命令是一样的,只需要将包管理器名称从 yum 改成 dnf 就行了。

# dnf listgit
# dnf history
# dnf history info
# dnf history undo
# dnf listgit
# dnf downgrade git-1.7.1-8.el6 perl-Git-1.7.1-8.el6

CentOS/Linux下设置IP地址

CentOS/Linux下设置IP地址

1、临时修改

1.1 修改IP地址

# ifconfig eth0 192.168.100.100

1.2 修改网关地址

# route add default gw 192.168.100.1 dev eth0

1.3 修改DNS

# echo “nameserver 8.8.8.8” >> /etc/resolv.conf

这个时候就可以上网了,上网的IP地址为192.168.100.100,网关地址为192.168.100.1。但是这样的设置是临时性的,一旦重启网卡或者重启服务器,除了1.3的操作其他均会被还原,这样的方式只适合临时IP修改,想要永久性修改网卡配置文件,就需要修改相应的文件

2、永久性修改

2.1 修改IP地址

修改/etc/sysconfig/network-scripts/ifcfg-eth0文件,如果有多张网卡,则修改相应的网卡

# vi /etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE=eth0 #网卡对应的设备别名
BOOTPROTO=static #网卡获得ip地址的方式(默认为dhcp,表示自动获取)
HWADDR=00:07:E9:05:E8:B4 #网卡MAC地址(物理地址)
IPADDR=192.168.100.100 #IP地址
NETMASK=255.255.255.0 #子网掩码
ONBOOT=yes #系统启动时是否激活此设备

2.2 修改网关地址

修改/etc/sysconfig/network文件

# vi /etc/sysconfig/network

NETWORKING=yes #表示系统是否使用网络,no表示不能使用网络
HOSTNAME=doiido #设置本机的主机名,要和/etc/hosts中设置的主机名相同
GATEWAY=192.168.100.1 #设置网关的IP地址
这个时候已经可以ping通IP地址,但是还无法ping通域名,因此需要修改DNS

2.3 修改DNS

修改/etc/resolv.conf文件

# vi /etc/resolv.conf

nameserver 8.8.8.8 #google域名服务器
nameserver 114.144.114.114 #国内域名服务器

2.4 重启网卡

# service network restart

正在关闭接口 eth0: [确定]
关闭环回接口: [确定]
弹出环回接口: [确定]
弹出界面 eth0: [确定]

这个时候,系统就可以正常的上网了

#注:其实网关地址和DNS也是可以写在ifcfg-eth0中,但是为了规范起见,将他们分开写