Wetts's blog

Stay Hungry, Stay Foolish.

0%

转自:http://www.cnblogs.com/zhoujinyi/p/5569462.html

概述

Redis-Sentinel 是 Redis 官方推荐的高可用性(HA)解决方案,当用 Redis 做 Master-slave 的高可用方案时,假如 master 宕机了,Redis 本身(包括它的很多客户端)都没有实现自动进行主备切换,而 Redis-sentinel 本身也是一个独立运行的进程,它能监控多个 master-slave 集群,发现 master 宕机后能进行自动切换。

它的主要功能有以下几点

  • 不时地监控 redis 是否按照预期良好地运行;
  • 如果发现某个 redis 节点运行出现状况,能够通知另外一个进程(例如它的客户端);
  • 能够进行自动切换。当一个 master 节点不可用时,能够选举出 master 的多个 slave(如果有超过一个 slave 的话)中的一个来作为新的 master,其它的 slave 节点会将它所追随的 master 的地址改为被提升为 master 的 slave 的新地址。

Sentinel 支持集群

很显然,只使用单个 sentinel 进程来监控 redis 集群是不可靠的,当 sentinel 进程宕掉后(sentinel 本身也有单点问题,single-point-of-failure)整个集群系统将无法按照预期的方式运行。所以有必要将 sentinel 集群,这样有几个好处:

  • 即使有一些 sentinel 进程宕掉了,依然可以进行 redis 集群的主备切换;
  • 如果只有一个 sentinel 进程,如果这个进程运行出错,或者是网络堵塞,那么将无法实现 redis 集群的主备切换(单点问题);
  • 如果有多个 sentinel,redis 的客户端可以随意地连接任意一个 sentinel 来获得关于 redis 集群中的信息。

运行 Sentinel

运行 sentinel 有两种方式:

  1. ```
    redis-sentinel /path/to/sentinel.conf
    1
    2
    2. ```
    redis-server /path/to/sentinel.conf --sentinel

以上两种方式,都必须指定一个 sentinel 的配置文件 sentinel.conf,如果不指定,将无法启动 sentinel。sentinel 默认监听 26379 端口,所以运行前必须确定该端口没有被别的进程占用。

Sentinel 的配置

Redis 源码包中包含了一个 sentinel.conf 文件作为 sentinel 的配置文件,配置文件自带了关于各个配置项的解释。典型的配置项如下所示:

1
2
3
4
5
6
7
8
9
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1

sentinel monitor resque 192.168.1.3 6380 4
sentinel down-after-milliseconds resque 10000
sentinel failover-timeout resque 180000
sentinel parallel-syncs resque 5

上面的配置项配置了两个名字分别为 mymaster 和 resque 的 master,配置文件只需要配置 master 的信息就好啦,不用配置 slave 的信息,因为 slave 能够被自动检测到(master 节点会有关于 slave 的消息)。需要注意的是,配置文件在 sentinel 运行期间是会被动态修改的,例如当发生主备切换时候,配置文件中的 master 会被修改为另外一个 slave。这样,之后 sentinel 如果重启时,就可以根据这个配置来恢复其之前所监控的 redis 集群的状态。

接下来我们将一行一行地解释上面的配置项:

1
sentinel monitor mymaster 127.0.0.1 6379 2

这一行代表 sentinel 监控的 master 的名字叫做 mymaster,地址为 127.0.0.1:6379,行尾最后的一个 2 代表什么意思呢?我们知道,网络是不可靠的,有时候一个 sentinel 会因为网络堵塞而误以为一个 master redis 已经死掉了,当 sentinel 集群式,解决这个问题的方法就变得很简单,只需要多个 sentinel 互相沟通来确认某个 master 是否真的死了,这个 2 代表,当集群中有 2 个 sentinel 认为 master 死了时,才能真正认为该 master 已经不可用了。(sentinel 集群中各个 sentinel 也有互相通信,通过 gossip 协议)。

除了第一行配置,我们发现剩下的配置都有一个统一的格式:

1
sentinel <option_name> <master_name> <option_value>

接下来我们根据上面格式中的 option_name 一个一个来解释这些配置项:

  • down-after-milliseconds
    • sentinel 会向 master 发送心跳 PING 来确认 master 是否存活,如果 master 在“一定时间范围”内不回应PONG 或者是回复了一个错误消息,那么这个 sentinel 会主观地(单方面地)认为这个 master 已经不可用了(subjectively down, 也简称为 SDOWN)。而这个 down-after-milliseconds 就是用来指定这个“一定时间范围”的,单位是毫秒。
    • 不过需要注意的是,这个时候 sentinel 并不会马上进行 failover 主备切换,这个 sentinel 还需要参考 sentinel 集群中其他 sentinel 的意见,如果超过某个数量的 sentinel 也主观地认为该 master 死了,那么这个 master 就会被客观地(注意哦,这次不是主观,是客观,与刚才的 subjectively down 相对,这次是 objectively down,简称为 ODOWN)认为已经死了。需要一起做出决定的 sentinel 数量在上一条配置中进行配置。
  • parallel-syncs
    • 在发生 failover 主备切换时,这个选项指定了最多可以有多少个 slave 同时对新的 master 进行同步,这个数字越小,完成 failover 所需的时间就越长,但是如果这个数字越大,就意味着越多的 slave 因为 replication 而不可用。可以通过将这个值设为 1 来保证每次只有一个 slave 处于不能处理命令请求的状态。
  • 其他配置项在 sentinel.conf 中都有很详细的解释。

所有的配置都可以在运行时用命令 SENTINEL SET command 动态修改。


转自:https://blog.csdn.net/yswKnight/article/details/78158540

什么是哨兵机制?

Redis 的哨兵(sentinel)系统用于管理多个 Redis 服务器,该系统执行以下三个任务:

  1. 监控(Monitoring):哨兵(sentinel)会不断地检查你的 Master 和 Slave 是否运作正常。
  2. 提醒(Notification):当被监控的某个 Redis 出现问题时,哨兵(sentinel)可以通过 API 向管理员或者其他应用程序发送通知。
  3. 自动故障迁移(Automatic failover):当一个 Master 不能正常工作时,哨兵(sentinel)会开始一次自动故障迁移操作,它会将失效 Master 的其中一个 Slave 升级为新的 Master,并让失效 Master 的其他 Slave 改为复制新的 Master;当客户端试图连接失效的 Master 时,集群也会向客户端返回新 Master 的地址,使得集群可以使用 Master 代替失效 Master。

哨兵(sentinel)是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel)进程,这些进程使用流言协议(gossip protocols)来接收关于 Master 是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个 Slave 作为新的 Master。

哨兵(sentinel)会向其它哨兵(sentinel)、master、slave 定时发送消息,以确认对方是否”活”着,如果发现对方在指定时间(可配置)内未回应,则暂时认为对方已挂(所谓的”主观认为宕机” Subjective Down,简称 sdown).

若“哨兵群”中的多数 sentinel,都报告某一 master 没响应,系统才认为该 master “彻底死亡”(即:客观上的真正down 机,Objective Down,简称 odown),通过一定的 vote 算法,从剩下的 slave 节点中,选一台提升为 master,然后自动修改相关配置。

虽然哨兵(sentinel)释出为一个单独的可执行文件 redis-sentinel,但实际上它只是一个运行在特殊模式下的 Redis 服务器,你可以在启动一个普通 Redis 服务器时通过给定 --sentinel 选项来启动哨兵(sentinel)。

哨兵(sentinel)的一些设计思路和 zookeeper 非常类似
1

哨兵模式的配置修改

实现步骤:

  1. 拷贝到 etc 目录
    • cp sentinel.conf /usr/local/redis/etc
  2. 修改 sentinel.conf 配置文件
    • sentinel monitor mymast 192.168.110.133 6379 1 #主节点 名称 IP 端口号 选举次数
    • #配置主服务器的密码(如没设置密码,可以省略)
    • sentinel auth-pass mymaster 123456
  3. 修改心跳检测 5000 毫秒
    • sentinel down-after-milliseconds mymaster 5000
  4. 做多多少合格节点
    • sentinel parallel-syncs mymaster 2
  5. 启动哨兵模式
    • ./redis-server /usr/local/redis/etc/sentinel.conf --sentinel &
  6. 停止哨兵模式

注意:

  1. 当启动哨兵模式之后,如果你的 master 服务器宕机之后,哨兵自动会在从 redis 服务器里面投票选举一个 master 主服务器出来;这个主服务器也可以进行读写操作!
  2. 如果之前宕机的主服务器已经修好,可以正式运行了。那么这个服务器只能进行读的操作,会自动跟随由哨兵选举出来的新服务器!
  3. 大家可以进入 ./redis-cli,输入 info,查看你的状态信息;

2

哨兵(sentinel)总结

Sentinel 的作用:

  1. Master 状态监测
  2. 如果Master 异常,则会进行 Master-slave 转换,将其中一个 Slave 作为 Master,将之前的 Master 作为Slave
  3. Master-Slave 切换后,master_redis.conf、slave_redis.conf 和 sentinel.conf 的内容都会发生改变,即 master_redis.conf 中会多一行 slaveof 的配置,sentinel.conf 的监控目标会随之调换

Sentinel 的工作方式:

  1. 每个 Sentinel 以每秒钟一次的频率向它所知的 Master,Slave 以及其他 Sentinel 实例发送一个 PING 命令。
  2. 如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线。
  3. 如果一个 Master 被标记为主观下线,则正在监视这个 Master 的所有 Sentinel 要以每秒一次的频率确认 Master 的确进入了主观下线状态。
  4. 当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认 Master 的确进入了主观下线状态, 则 Master 会被标记为客观下线 。
  5. 在一般情况下,每个 Sentinel 会以每 10 秒一次的频率向它已知的所有 Master,Slave发送 INFO 命令。
  6. 当 Master 被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次 。
  7. 若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除。
  8. 若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除。

The problem was solved by changing the

1
$app->run();

in /public/index.php to

$request = Illuminate\Http\Request::capture();

1
$app->run($request);

keymaps为Mac OS X 10.5+

debug

  • 跳到下一步(Step Over 相当于eclipse的f6):F8 (Win)
  • 进入到代码(Step Into 相当于eclipse的f5):F7 (Win)
  • 跳过:F9 (Win)
  • 运行到光标处:Alt + F9 (Win)

搜索

  • 文件
    • 通过类名搜索类文件:command + o (Mac)、 ctrl + n (Win)
    • 通过文件名搜索文件:command + shift + o (Mac)、 ctrl + shift + n (Win)
    • 文件名全局搜索(所有文件):double shift (Mac、Win)
  • 内容
    • 搜索文件内容:ctrl + shift + f (Win)

      历史记录

  • 光标
    • 查看上下步:command + alt + 左右方向键 (Mac)、 ctrl + alt + 左右方向键 (Win)
    • 跳转到上次编辑的地方:command + shift + backspace (Mac)、 ctrl + shift + backspace (Win)
    • 跳到大括号的开头结尾:ctrl + [或者] (Win)
  • 文件
    • 列出最近查看的文件列表:command + e (Mac)、 ctrl + e (Win)
    • 最近修改文件列表:shift + command + e (Mac)、 ctrl + shift + e (Win)

查看

  • 其他
    • 查看文档:ctrl + j (Mac)、ctrl + q (Win)
    • 查看文件内容纲要:command + F12 (Mac)、 ctrl + F12 (Win)
    • 查看当前方法的声明:alt + q (Win)、option + space (Mac)
  • 继承
    • 查看方法、类的super方法:command + u (Mac)、ctrl + u (Win)
    • 查看接口、方法、类的实现:command + alt + b (Mac)、ctrl + alt + b (Mac)
  • 继承关系图
    • 查询方法super、继承关系图(Call Hierarchy):command + shift + h (Mac)
    • 查询类super、继承关系树图(Type Hierarchy):ctrl + h (Mac)
    • 查看类的层次结构图(Diagram):command + alt + shift + u (Mac)、ctrl + alt + shift + u (Win)
  • 引用查找
    • 查看类、方法、变量的引用:command + b (Mac)、ctrl + b (Win)
    • 搜索对象被引用的地方:alt + F7 (Mac & Win)
    • 搜索对象在当前文件被引用的地方:command + F7 (Mac)、 ctrl + F7 (Win)
  • 光标
    • 跳转到某行:ctrl + g (Win)
    • 跳转到第一行:ctrl + Home (Win)
    • 跳转到第一行:ctrl + End (Win)

编辑

  • 整行编辑
    • 删除行:command + delete (Mac)、 ctrl + y (Win)
    • 向下插入新行:command + shift + enter (Mac)、 shift + enter (Win)
    • 向上插入新行:command + alt + enter (Mac)、 ctrl + alt + enter (Win)
    • 向上下移动当前行:shift + alt + 上下方向键 (Mac & Win)
    • 剪切当前行:command + x (Mac)、 ctrl + x (Win)
    • 复制当前行:command + c (Mac)、 ctrl + c (Win)
    • 将当前行复制到到下一行:command + d (Mac)、 ctrl + d (Win)
    • 粘贴:command + v (Mac)、 ctrl + v (Win)
    • 注释:command + / (Mac)、 ctrl + / (Win)
    • 整合两行:ctrl + shift + j (Win)
  • 内容
    • 替换文件内容:ctrl + shift + r (Win)
    • 格式化代码:command + alt + l (Mac)、 ctrl + alt + l (Win)
    • 将选择的内容转换大小写:command + shift + u (Mac)、 ctrl + shift + u (Win)
    • 选择代码块:ctrl + w (Win)
  • 提示
    • 代码模版:ctrl + j (Win)
    • 错误内容提示:alt + enter (Mac & Win)
    • get\set\构造方法等生成:alt + Insert (Win)
  • 文件
    • 修改文件名:shift + F6 (Win)
  • 其他
    • 撤销:ctrl + z (Win)
    • 取消撤销:ctrl + shift + z (Win)
    • 自动导入包、删除多余的包:alt + ctrl + o (Mac、Win)

  • psvm:public static void main
  • sout:System.out.println

  1. Accept属于请求头, Content-Type属于实体头。

Http报头分为通用报头,请求报头,响应报头和实体报头。

请求方的http报头结构:通用报头|请求报头|实体报头

响应方的http报头结构:通用报头|响应报头|实体报头

  1. Accept代表发送端(客户端)希望接受的数据类型。
阅读全文 »

这些都是典型的使用GNU的AUTOCONF和AUTOMAKE产生的程序的安装步骤。

  • ./configure 是用来检测你的安装平台的目标特征的。比如它会检测你是不是有CC或GCC,并不是需要CC或GCC,它是个shell脚本。
  • make 是用来编译的,它从Makefile中读取指令,然后编译。
  • make install 是用来安装的,它也从Makefile中读取指令,安装到指定的位置。

AUTOMAKE和AUTOCONF 是非常有用的用来发布C程序的东西。如果你也写程序想使用AUTOMAKE和AUTOCONF,可以参考CNGNU.ORG上的相关文章。

1、configure,这一步一般用来生成 Makefile,为下一步的编译做准备,你可以通过在 configure 后加上参数来对安装进行控制,比如

1
2
3
4
5
6
./configure --prefix=/usr
# 上面的意思是将该软件安装在 /usr 下面,执行文件就会安装在 /usr/bin (而不是默认的 /usr/local/bin),资源文件就会安装在 /usr/share(而不是默认的/usr/local/share)。同时一些软件的配置文件你可以通过指定 --sys-config= 参数进行设定。有一些软件还可以加上 --with、--enable、--without、--disable 等等参数对编译加以控制,你可以通过允许
./configure --help
# 察看详细的说明帮助。
./configure --prefix
# 作用不指定prefix,则可执行文件默认放在/usr/local/bin,库文件默认放在/usr/local/lib,配置文件默认放在/usr/local/etc。其它的资源文件放在/usr/local/share。你要卸载这个程序,要么在原来的make目录下用一次make uninstall(前提是make文件指定过uninstall),要么去上述目录里面把相关的文件一个个手工删掉。指定prefix,直接删掉一个文件夹就够了。

2、make,这一步就是编译,大多数的源代码包都经过这一步进行编译(当然有些perl或python编写的软件需要调用perl或python来进行编译)。如果在 make 过程中出现 error ,你就要记下错误代码(注意不仅仅是最后一行),然后你可以向开发者提交 bugreport(一般在 INSTALL 里有提交地址),或者你的系统少了一些依赖库等,这些需要自己仔细研究错误代码。

3、make install,这条命令来进行安装(当然有些软件需要先运行 make check 或 make test 来进行一些测试),这一步一般需要你有 root 权限(因为要向系统写入文件)。

4  卸载   make uninstall

访问日志

能够使用access_log指令的字段包括:http、server、location。

需要注意的是:Nginx进程设置的用户和组必须对日志路径有创建文件的权限,否则,会报错。

访问日志格式配置

log_format用来设置日志格式,也就是日志文件中每条日志的格式,具体如下:

1
log_format name(格式名称) type(格式样式)

举例说明如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
log_format  main  '$server_name $remote_addr - $remote_user [$time_local] "$request" '
'$status $uptream_status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$ssl_protocol $ssl_cipher $upstream_addr $request_time $upstream_response_time';


$server_name:虚拟主机名称。
$remote_addr:远程客户端的IP地址。
-:空白,用一个“-”占位符替代,历史原因导致还存在。
$remote_user:远程客户端用户名称,用于记录浏览者进行身份验证时提供的名字,如登录百度的用户名scq2099yt,如果没有登录就是空白。
[$time_local]:访问的时间与时区,比如18/Jul/2012:17:00:01 +0800,时间信息最后的"+0800"表示服务器所处时区位于UTC之后的8小时。
$request:请求的URI和HTTP协议,这是整个PV日志记录中最有用的信息,记录服务器收到一个什么样的请求
$status:记录请求返回的http状态码,比如成功是200。
$uptream_status:upstream状态,比如成功是200.
$body_bytes_sent:发送给客户端的文件主体内容的大小,比如899,可以将日志每条记录中的这个值累加起来以粗略估计服务器吞吐量。
$http_referer:记录从哪个页面链接访问过来的。
$http_user_agent:客户端浏览器信息
$http_x_forwarded_for:客户端的真实ip,通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。
$ssl_protocol:SSL协议版本,比如TLSv1。
$ssl_cipher:交换数据中的算法,比如RC4-SHA。
$upstream_addr:upstream的地址,即真正提供服务的主机地址。
$request_time:整个请求的总时间。
$upstream_response_time:请求过程中,upstream的响应时间。

访问日志路径配置

access_log指令用来指定日志文件的存放路径(包含日志文件名)、格式和缓存大小,具体如下:

1
access_log path(存放路径) [format(自定义日志格式名称) [buffer=size | off]]

举例说明如下:

1
access_log  logs/access.log  main;

关闭某个日志

1
2
3
location = /favicon.ico {  
access_log off;
}

错误日志

错误日志主要记录客户端访问Nginx出错时的日志,格式不支持自定义。通过错误日志,你可以得到系统某个服务或server的性能瓶颈等。因此,将日志好好利用,你可以得到很多有价值的信息。错误日志由指令error_log来指定,具体格式如下:

error_log path(存放路径) level(日志等级)

path含义同access_log,level表示日志等级,具体如下:

[ debug | info | notice | warn | error | crit ]

从左至右,日志详细程度逐级递减,即debug最详细,crit最少。

举例说明如下:

1
error_log  logs/error.log  info;

需要注意的是:error_log off并不能关闭错误日志,而是会将错误日志记录到一个文件名为off的文件中。

正确的关闭错误日志记录功能的方法如下:

1
error_log /dev/null;

上面表示将存储日志的路径设置为“垃圾桶”。

日志

分析

分析工具为 goaccess-nginx

目前,我们可以通过这款软件查看的统计信息有:

  • 统计概况,流量消耗等
  • 访客排名
  • 动态Web请求
  • 静态web请求,如图片、样式表、脚本等。
  • 来路域名
  • 404 错误
  • 操作系统
  • 浏览器和搜索引擎
  • 主机、DNS和ip地址
  • HTTP 响应代码
  • 引荐网站
  • 键盘布局
  • 自定义显示
  • 支持超大日志(分析速度很快)
  1. 语法
    1
    goaccess [ -b ][ -s ][ -e IP_ADDRESS][ -a ] <-f log_file >
  • 参数
    1
    2
    3
    4
    5
    -f – 日志文件名
    -b – 开启流量统计,如果希望加快分析速度不建议使用该参数
    -s – 开启HTTP响应代码统计
    -a – 开启用户代理统计
    -e – 开启指定IP地址统计,默认禁用
  • 例子
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    goaccess -f access.log

    # 参数以显示HTTP响应代码、用户代理、流量消耗
    goaccess -f access.log -s -a -b

    zcat access.log.1.gz | goaccess

    # 分析目前下所有日志
    zcat access.log* | goaccess

    # 10月5号那天的日志
    sed -n ‘/05/Dec/2010/,$ p’ access.log | goaccess -s -b

    # 分析从11月5号到12月5号一个月内的日志
    sed -n ‘/5/Nov/2010/,/5/Dec/2010/ p’ access.log | goaccess -s -b

    # 通过调用本地的goaccess程序来分析服务器上的日志
    ssh user@server 'cat /var/log/apache2/access.log' | goaccess -s -a -b

    # 获取某个时间段的日志
    # 方法1:sed
    cat access_nginx.log | egrep "12/Sep/2016" | sed -n '/09:00:00/,/09:30:00/p'
    # 方法二:awk
    cat web.log | egrep "01/Apr/2014" | awk -F':' '$2 = 21 && $3 >= 30 && $3 <= 50'

Bean Validation 1.0(JSR-303)

@Null 被注释的元素必须为 null

@NotNull 被注释的元素必须不为 null

@AssertTrue 被注释的元素必须为 true

@AssertFalse 被注释的元素必须为 false

@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值

@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值

阅读全文 »

1. Intellj IDEA显示行号

1
File>setting>editor>appearance>general>show line numbers

2. src中资源文件编译进classes文件夹

IDEA的maven项目中,默认源代码目录下的xml等资源文件并不会在编译的时候一块打包进classes文件夹,而是直接舍弃掉。

Eclipse的src目录下的xml等资源文件在编译的时候会自动打包进输出到classes文件夹。

阅读全文 »

php 和 java 的区别

  1. php 是解释型语言。java 是编译型语言
  2. php 子类构造方法不能自动调用父类的构造方法,java 子类构造方法自动调用父类的无参构造方法,如果没有无参构造方法,则必须手动调用有参构造方法
  3. php 是弱类型语言。java 是强类型语言