nginx lua 模块编译

背景:https://www.clarkhu.net/?p=10121 (需要使用request_id定位业务问题)

参考文章:

https://github.com/openresty/lua-nginx-module#nginx-compatibility

需要的安装包有:

nginx-1.19.3.tar.gz
lua-nginx-module-0.10.14.tar.gz
ngx_devel_kit-0.3.1.tar.gz
openssl-1.0.2j.tar.gz
pcre-8.36.tar.gz
luajit2-2.1-20210510.tar.gz

make PREFIX=/usr/local/luajit
make install PREFIX=/usr/local/luajit
export LUAJIT_LIB=/usr/local/luajit/lib
export LUAJIT_INC=/usr/local/luajit/include/luajit-2.1


tar zxf lua-nginx-module-0.10.14.tar.gz
tar zxf ngx_devel_kit-0.3.1.tar.gz
tar xvzf nginx-1.19.3.tar.gz

./configure --prefix=/usr/local/nginx-1.19.3 --with-http_ssl_module --with-openssl=/usr/local/src/openssl-1.0.2n --with-pcre=/usr/local/src/pcre-8.36 --with-http_secure_link_module --with-ld-opt=-Wl,-rpath,/usr/local/luajit/lib --add-module=/usr/local/src/ngx_devel_kit-0.3.1 --add-module=/usr/local/src/lua-nginx-module-0.10.14

make -j2
make install

这里主要的是nginx, lua-nginx ngx_devel luajit 这几个包的兼容性问题需要自己去查和测试。之前遇到了resty.core not found ,上网搜了下,主要就是包的兼容性问题导致的

Nginx 使用requestid 对应用程序日志及性能追踪

问题描述:业务侧经常会遇到一个问题,可以拿到某个慢查询的SQL(比如mysql slowlog, 或是使用的云产品打开实例页面查看对应的慢日志),但是确很难找到对应的业务代码在哪里?(除非SQL本身具有特殊识别性,或是对业务系统非常之熟悉外,如果很雷同的,找起来确实很痛苦,亲测是这样)

针对上面出现的这个问题,nginx request_id 可以完美解决

nginx 从1.11 之后支持生成request_id

部署方案:

1.nginx 接入层关键配置

map $http_x_log_request_id $log_request_id {
    default $http_x_log_request_id;
    -       $request_id;
    ""      $request_id;
}

location ~ .*\.(php|php5)?$ {
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index   index.php;
    fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param   LOG_REQUEST_ID $log_request_id;
    include         fastcgi_params;
    fastcgi_intercept_errors on;
    error_page      500 502 503 504  /50x_php.html;
}

2.业务层WEB框架入口代码:设置全局变量

$GLOBALS['LOG_REQUEST_ID'] = !empty($_SERVER['LOG_REQUEST_ID']) ? $_SERVER['LOG_REQUEST_ID'] : $_SERVER['REQUEST_TIME_FLOAT'];

3.业务层JOB框架入口代码:设置全局变量,由于job不经过nginx层,所以request_id自己生成

<?php
$job_request_id = md5("{$script_name}." . microtime(true));
$GLOBALS['LOG_JOB_REQUEST_ID'] = $job_request_id;
?>

4.业务日志收集到文件

<?php
....
$log['controller'] = controller值
$log['action'] = action值
$log['url'] = 当前请求的url, 可以用$_SERVER['REQUEST_URI']获取;
$log['refer'] = //refer, 可以从$_SERVER获取;
$log['user_agent'] = user_agent值,可以从$_SERVER获取;
$log['ip'] = ip获取函数
$log['http_status'] = http状态码,可以从$_SERVER获取;
$log['log_request_id'] = isset($GLOBAL['LOG_REQUEST_ID']) ? isset($GLOBAL['LOG_REQUEST_ID']) : '';
write_log(json_encode($log));
....
?>

5.将第三步写的log导入到es中,便于查询log_request_id对应的请求来源

6.框架SQL执行处代码修改:

$comment_token = '';
if(defined('IS_JOB') && IS_JOB) {
	if(isset($GLOBALS['LOG_JOB_REQUEST_ID']) && !empty($GLOBALS['LOG_JOB_REQUEST_ID'])) {
		$comment_token = '/*job_' . $GLOBALS['LOG_JOB_REQUEST_ID'] . '*/';
	}
} else {
	if(isset($GLOBALS['LOG_REQUEST_ID']) && !empty($GLOBALS['LOG_REQUEST_ID'])) {
		$comment_token = '/*web_' . $GLOBALS['LOG_REQUEST_ID'] . '*/';
	}
}
$sql = $sql . $comment_token;

$this->_result = $this->_execute($sql);

这里在执行的SQL语句后面接上/*request_id*/,并不影响SQL本身的执行,与此同时还能知道SQL的来源,下图为慢日志查询中显示的SQL语句,带上了request_id, 这样是不是就可以得容易知SQL语句来自业务哪了呢?

根据上述步骤1,2,3,4,5,就可以根据慢日志查询的SQL, 反查到对应的业务请求来源了,是不是很帅?

远离故障的十大原则

文章引自: https://my.oschina.net/u/3705388/blog/3130038  觉得非常之认可,写的都非常棒,特此记录

故障是运维人员永远的痛。相信每一个运维人员的KPI中都有一项:可用性。可用性高就是不出故障,各个公司对可用性和故障评级的标准都不相同,但是避免故障的方法却是殊途同归。我们怎么避免故障,沃趣科技简单列举了以下几条,与大家共勉!

  • 变更要有回滚,在同样的环境测试过
  • 对破坏性的操作谨慎小心
  • 设置好命令提示
  • 备份并验证备份的有效性
  • 对生产环境存有敬畏之心
  • 交接和休假最容易出故障,变更请谨慎
  • 搭建报警,及时获取出错信息
  • 自动切换需谨慎
  • 仔细一点,偏执一点,检查,检查,再检查
  • 简单即是美

【远离故障的十大原则之1】变更要有回滚,在同样的环境测试过

也是运维最繁琐,最苦逼的地方,所有的变更都必须有回滚的办法,在同样的环境下测试过。没有做过的东西,总是会在你意想不到的地方给你一次痛击,在阿里巴巴的这么多年运维经验告诉我们,所有没有做过的变更,出错的概率最大。所以我们需要给变更以回滚的可能,在各个步骤可能出错的情况下,考虑回滚到最初状态。优秀的运维人员对不考虑回滚的的操作都是敬而远之的,从某种意义上来说,运维是一门经验的学科,是一门试错的学科。

【远离故障的十大原则之2】对破坏性的操作谨慎小心

破坏性的操作有哪些列?对数据库来说有:DROP Table, Drop database, truncate table,delete all data;这些操作做完了以后几乎无法考虑怎么把数据都回滚回去了。就算回滚,代价也是非常大的。你执行这样的语句非常简单,但是回滚恢复数据缺非常困难。linux的命令rm可以-r(recursive)递归的删除某一个目录,-f(force)强制删除,但是你有没有删错过文件。我们遇到过一个文件名中末尾有空格的情况,而有的同事rm -r习惯性的会在文件名后面加*,这样就成了rm -r aa *,所有当前目录的数据都被删除掉了!经过这次故障以后我们给rm做了别名:
alias rm=’rm -i –‘
这样在删除数据时,rm命令会提示你,是否确认删除该文件。
同样的cp和mv也可以有同样的选项:
alias cp=’cp -i –‘
alias mv=’mv -i –‘ 

【远离故障的十大原则之3】设置好命令提示

让你时刻知道你在操作哪个数据库,让你知道你在哪个目录下。mysql字符客户端允许你设置提示符,默认的提示符就是一个光秃秃的mysql >,为了让你清楚的知道你当前是以哪个用户名,哪个IP(可能是localhost,127.0.0.1或者具体的物理IP),你当前操作的是哪个schema,以及当前的时间,你可以设置数据库的提示符为:prompt=”\\u@\\h : \\d \\r:\\m:\\s> “。它可以直接写在my.cnf的[mysql]下,这样你每次连上MySQL就默认显示如下: root@127.0.0.1 : woqutech 08:24:36>

具体prompt可以设置哪些提示,你可以参考http://dev.mysql.com/doc/refman/5.6/en/mysql-commands.html 中的列表,而linux命令提示符也允许你设置的。有两个地方可以设置。

第一个:PS1。这个是每次shell提示你输入命令的信息,默认为:$或者#,只会提示你是超级用户还是普通用户。有经验的运维者会设置export PS1=’\n\e[1;37m[\e[m\e[1;31m\u\e[m\e[1;31m@\e[m\e[1;31m\h\e[m \e[4m`pwd`\e[m\e[1;37m]\e[m\e[1;36m\e[m\n\$’。这样你就可以知道你当前的目录,登录的用户名和主机信息了,示例提示符如下:
[root@woqu-lsv-01 /home/mysql] #
你可以查看http://www.cyberciti.biz/tips/howto-linux-unix-bash-shell-setup-prompt.html获得具体的PS1设置颜色,设置各个提示内容的介绍。

第二个提示符就是PROMPT_COMMAND。这个是设置你连到具体的数据库以后标签页标题上显示的内容,Windows用户可能会用securtCRT,Mac用户可能会用iTerm2,开多个标签页的话,如果每个标签页的标题上内容一样,我们切来切去就有可能在错误的标签页上做操作,设置了这个以后,这个问题概率就会小很多。比如我们的机器上设置为PROMPT_COMMAND=’echo -ne “\033]0;${USER}@${HOSTNAME%%.*}”; echo -ne “\007″‘对应的标签页如下图

【远离故障的十大原则之4】备份并验证备份有效性

是人总会出错,是机器总可能会有突然崩溃的那一天。怎么办-我们需要准备备份。备份的学问很大。按照不同的纬度可以分为:冷备份和热备份;实时备份和非实时备份;物理备份和逻辑备份。

互联网企业为了提供7*24小时不间断的服务,数据库就需要有实时热备份。在主库出现问题的情况下能够由备库提供服务。备库是否有效,数据是否一致,主库出现问题的时候怎么切换都需要运维人员认真考虑。

是不是有了这些就够了列?不行,应用程序也是人写的,曾经出现过程序一不小心delete语句没有带任何条件,导致一个表中所有的数据都被删除的惨状。所以你除了实时的备份,还需要有非实时的备份,在你的数据出现逻辑错误之后能够从备份数据中恢复出来。现在很多人在研究MySQL模仿oracle的flashback功能,利用binlog来恢复数据。但是这样的话,binlog_format必须设置为row并且对于DDL操作也无法回滚。它是为快速解决部分数据被错误删除的解决方案,但是无法代替非实时备份的作用。

非实时备份有可以分为在线延时备份和离线备份。在线延时备份是搭建数据库的一定时间延迟的热备份,比如MySQL就可以搭建一个延迟一天的slave,一直保持着备库与主库的延迟在一天。可以利用pt-slave-delay工具来实现这个功能。另外,离线备份是目前大家用的比较多的,可以利用mysqldump进行逻辑备份或者xtrabackup进行物理备份。为了空间的原因和快速恢复考虑,你还可以利用xtrabackup进行增量的物理备份。

备份有了,是否就可以高枕无忧了?还是不行。你需要验证备份的有效性。没有一个备份能够保证它备份出来的数据能够100%恢复出正确的数据,特别是物理备份的概率相对来说,更低,xtrabackup备份一个月总有那么几次来大姨妈,不能给你很好的服务。所以,备份并不只是备份,它还包括备份的验证,它如果不能恢复出正确的数据,就只是浪费空间而已。备份的验证最简单的就是找一个空闲的库,来恢复出来,mysql启动以后检查部分数据。如果不需要这么严谨,对于xtrabackup来说,你至少得验证它–apply-log能够恢复上去吧?同样,备库的数据一致性也需要经常检查一下,mysql的replication并不保证100%的数据一致性,你可以去翻翻mysql statement复制的bug列表,有些数据在主备不同的环境上分别执行,数据就会不一样。可以考虑用percona的工具pt-table-checksum来检查主备不一致,用pt-table-sync来同步主备数据

【远离故障的十大原则之5】对生产环境存有敬畏之心

这应该是运维者进入行业首先需要具备的素质。但是我们还是需要把它拿出来强调一下。有机会的话,你可以梳理一下:

你的生产环境上有哪些账户,这些账户是否都确实需要登录到机器上来?这些账户即包括linux用户还包括数据库账户。

你的root用户是否开放给了某些用户,这些用户安全吗?

你的用户密码是否经常修改,是否加密不让具体的操作人员直接看到,密码强度时候足够,密码重试次数达到一定次数是否黑名单;

你的生产环境和线下环境是否隔离,数据库是否和外网隔离?

是否一些工作明明能够在开发库和测试库做,却被放到生产环境上去了。

是否有专门的人负责线上应用的发布,从而避免开发人员直接接触生产环境

【远离故障的十大原则之6】交接和休假最容易出故障,变更请谨慎

这个是经验之谈。我们在总结故障的情况时,发现在公司部门有变化时,工作交接(不管是休假,工作职责变化还是离职),故障的出现频率会比正常情况下多50%以上。有人说,这是因为机器或者应用是有感情的,舍不得离开的运维者。

我们不谈感情,简单的理性分析一下。公司或者部门难免会做一些调整,变化是世界上唯一不变的事情。而运维人员是一线做事情的人,部门调整或者领导的更换可能导致工作的着重点不同,做事的方式和评测的标准变了,适应过程中难免会出现一些考虑不周到的地方,出故障也是情理之中了。

而工作交接,对运维人来说,其实是一个非常费时费力的事情,你需要把所有平常做的工作都梳理清楚,甚至包括你的一些经意不经意的操作习惯,这样的话,下一个人才可能接手的下来。比如:你可能认为备库正常情况下没有访问,于是让某些并不重要的任务(一个月一次抽取部分数据到线下测试?)直接连备机IP进行操作。下一个人接手,认为备机就是备机,操作起来不会有任何问题,结果下一次任务抽取就是一个故障出来了。再举一个我们遇到了事例吧:同事A出国休假了,休假期间估计联系不上,他留了文档,并告诫说某几个库和表是比较核心和容易出问题的,没有特殊情况最好等他回来再做变更。正好,休假期间,开发人员找到同事B,要求他重置一个字段的某一位(bit),并打包票说这个bit没有用,同事B拒绝,并背上了不配合的骂名。同事A回来吓了一身冷汗,原来这个字段已经被另外一个离职的开发使用了。

所以,运维部门和运维人员对变化需要尽量放平心态;接手别人的工作要一而再,再而三的确认变更方案。请教人并不见得就是能力不行的表现;休假前最好各种可以做好的事情,最好能够准备一份文档,指明在什么情况下怎么做和联系哪些人。在别人放假的时候接手工作,“能拖则拖”,实在需要执行:必须不厌其烦的跟原运维者确认各个操作细节

【远离故障的十大原则之7】搭建报警,及时获得出错信息

搭建性能监控,了解历史,获得趋势,预测未来。运维的最高境界不是故障来了,泰山崩于前而不惊,苍老师勾引你而抗日;而是没有故障,让故障消失在萌芽之中。请给那些默默无闻,每天想着我们的系统还存在哪些隐患,怎么解决,怎么及早发现的运维人员鼓掌。他们是最可爱的人。而他们赖以生存的工具就是报警和监控。Oracle发展了这么多年,awr和相关的性能参数都相对比较全;MySQL现在也已经迎头赶上,配套的工具越来越多。

报警可以让你及时知道系统出现了什么异常。比如slave io报警,在数据库replication异常的时候就会提醒你:IO线程出现了问题,可能是网络问题,主数据库问题等,slave sql报警会提醒你replication的SQL线程出现了问题,可能是主备不一致,slave被停掉了,存储过程在备机有异常或者其他问题。这样你收到报警就可以及时跟进,而不至于主备长时间不一致,主库坏掉了想要切换到备库的时候却不能切换。

性能监控可以让你了解系统的历史性能信息。分析故障发生时的各种现象,确认故障的真正原因;了解变化趋势,发现故障的苗头,及早优化和调整。比如你如果使用了PCI-E的Flash卡,你可以监控logical_written_bytes,logical_read_bytes,physical_written_bytes,physical_read_bytes以便获得flash卡的每秒的逻辑读写和物理读写字节数。对于MySQL你可以监控Com_delete+Com_delete_multi, Com_insert+Com_insert_select,Com_update+Com_update_multi,Com_select来获得每秒的MySQL DML删除,插入,更新和查询的次数。

报警和性能监控其实不不完全独立的,很多性能的监控项也可以报警出来。比如linux的iostat中的await_time可以作为性能监控采集起来获得系统IO响应时间的变化曲线,当该值达到20以上的时候,也可以报警出来,让运维人员跟进是磁盘阵列中坏了一块,还是异常的数据拷贝影响了系统的IO性能等

【远离故障的十大原则之8】自动切换需谨慎

现在数据库的HA很多都是进行自动切换的,这样运维人员深夜起来手工切换到备库的机会就会少很多。切换也会快速很多。但是,它带来的副作用也不容忽视。

现在业界使用的HA软件非常多,heartbeat由于很多SA兼作DBA的运维比较熟悉,在MySQL自动切换也是不少的。一般来说,它会通过mysqladmin ping来探测MySQL是否存活,如果发现异常,那么他就会切换VIP和MySQL资源到备库。但是此时备库的数据延迟是否为0,主库crash之后binlog的数据是否全部都同步到备库上去了,备库的read_only是否关闭,这些heartbeat都不管。我们想象一下,主库上应用提交了一笔订单,结果发生了切换,这笔订单没有同步到备库上,卖家也就损失了一个销售单,对客户,对公司都是非常大的影响。

当然,自动切换也不能全盘否定,它能够更快速的将应用切换到新的热备份备库上,应用的不可用时间大大缩短。只是我们要好好利用这一把双刃剑,仔细评估它的影响,降低或者去除副作用,让它为我们服务

【远离故障的十大原则之9】仔细一点,偏执一点,检查,检查,再检查

之前我跟一个资深的运维学习线上操作的时候,觉得这家伙有点变态,他在做一个变更的时候,会先提前一两周发送邮件并电话手机的通知相关人;在测试机上写好脚本,召集大家review操作步骤和脚本;测试完成以后拷贝到生产环境;登录对应机器,“打开,关闭,打开,关闭”该脚本;跟相关人员再次确认执行的操作,顺序,时间点,可能的影响和回滚是否都准备好了;执行前还要退出这个机器,然后再登录进去,“打开,关闭”脚本;最后才在后台运行脚本,在另外一个窗口登录着,随时ps和查看结果输出。期间姿势端正,呼吸急促而均匀,眼神凝重。操作的人不觉得累,倒是一边学习的人很累。

当我做到一定程度,我也开始这样了。医学上,这种好像叫做强迫症。唉,提前通知会让大家都有准备,也避免了临时相关人员过来说这个操作和其他操作有依赖需要调整操作时间的问题; 召集大家review步骤和脚本是为了让大家一起来看看整个过程中还有哪些依赖没有考虑到或者哪些细节没有注意到,三个臭皮匠顶一个诸葛亮在运维来说是金科玉律;“打开,关闭,打开,关闭”是为了一再确认脚本拷贝过来是否正确,目录时候正确,思考在测试环境运行和在生产环境运行有什么不一样的;退出再登录机器是为了确认我登录的机器确实没有错;在后台运行是担心网络突然中断,我的脚本运行到一半怎么办;调整呼吸和端正姿势是为了对这个操作的敬重,对自己工作和运维工作的尊重。

以MySQL 使用flash卡为例吧。flash算是一个比较新的事务,提供的IO比普通磁盘是几个数量级的提升。要想在生产环境使用,首先我们需要对他进行详尽的评估和破坏性测试,设置各种参数,考虑他们在各种场景下使用的配置;24小时不间断的进行半个月读写操作,中途突然掉电;高并发,高吞吐量下的测试;温度湿度极限测试;预留空间释放测试等等。然后我们会尝试在测试库上部署试用,收集和修改各个配置已达到最稳定,最高性能的配置;运行稳定以后我们才考虑在线上备库使用,并且主备要求异构;适当的时机切换为使用新的flahs卡为主库,万一出现了问题,还可以切换回原主机。

这里也跟大家简单介绍一下screen命令,这个命令会在服务器段开启一个session,就算你的网络断掉了,你的脚本也会自动在后台运行。screen -S woqutech可以开启一个woqutech命令的后台session;如果你的网络断掉了,你可以用screen -dr woqutech连上之前的session继续进行操作。IBM的文档库中有一个非常靠谱的文档:http://www.ibm.com/developerworks/cn/linux/l-cn-screen/

【远离故障的十大原则之10】简单即是美

最后一条有点禅的意境了。它和Unix的思想不谋而合。我们总是面临着各种诱惑:新的系统架构,新的更智能的命令和工具,最新的硬件平台,功能更全的HA软件等。他们总是以各种各样的方式吸引我们,most exciting,unbelievable,让你欲罢不能。你可以在线下安装,测试,怎么搞都行。但是如果想要在生产环境下使用起来,那就得经过非常详细,非常漫长,各种方式验证其稳定性的过程。

能够使用系统内置命令的话,就不用考虑其他要专门下载安装的软件了;脚本本身就能完成的功能,就没有必要专门找一个功能丰富的软件来做;linux本身自带的字符界面比那些复杂的图形界面要简洁方便;MySQL的一些分区,生僻函数,没有必要的话不要使用。

正向代理与反向代理

今天早上看了篇nginx文章,提到了反向代理,其实十年前入职时,就听到用nginx 做反向代理,其实当时并不太清楚什么叫反向代理,记得当时我还拿这个去问前辈同事,在这之前只听过代理(比如为了访问google,使用代理软件,需要在浏览器配置代理的地址,然后通过代理访问),今天早上再次看到nginx相关的书,想总结一下正向代理和反向代理的区别

首先得弄清楚什么是正向代理,才能了解什么是反向代理?

正向代理

举个例子:

我是一个用户,我访问不了某个网站,但是我能访问一个代理服务器,这个代理服务器,它能访问那个我不能访问的网站,于是我先连上代理服务器,告诉他我需要的那个无法访问的网站,代理服务器帮我取回来,然后返回给我。从网站的角度看,只在代理服务器来取内容时有一次记录,有时候并不知道是用户的请求,也隐藏了用户资料,这取决于代理告不告诉网站

客户端必须设置正向代理服务器,当然前提是要知道正向代理服务器的ip地址,还有代理程序的端口。

总结:正向代理是一个位于客户端和原始服务器之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原服务器转交请求,并将获得的内容返回给客户端,客户端必须要进行一些特别的设置才能使用正向代理

正向代理的用途

访问原来无法访问的资源
做缓存,加速访问资源
对客户端访问授权,上网进行认证
上网行为管理,对外隐藏用户信息

反向代理

反向代理,客户端是无感知代理的存在的,反向代理对外都是透明的,访问者者并不知道自己访问的是一个代理。因为客户端不需要任何配置就可以访问

反向代理实际运行方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外表现为一个服务器。

反向代理的用途

(1)保证内网的安全,可以使用反向代理提供WAF功能,阻止web攻击, 通常将反向代理作为公网访问地址,Web服务器是内网

(2)负载均衡,通过反向代理服务器来优化网站的负载

反向代理一般用来作负载均衡的比较多

nginx 的反向代理

nginx支持配置反向代理,通过反向代理实现网站的负载均衡。这部分先写一个nginx的配置,后续需要深入研究nginx的代理模块和负载均衡模块。

nginx通过proxy_pass_http 配置代理站点,upstream实现负载均衡。

nginx 反向代理配置负载均衡

参考资料: https://www.cnblogs.com/anker/p/6056540.html

分布式与集群的区别

分布式:一个业务分拆多个子业务,部署在不同的服务器上。
集群:同一个业务,部署在多个服务器上

举例说明:
小饭店原来只有一个厨师,切菜洗菜备料炒菜全干,后来客人多了,厨房一个厨师忙不过来,又请了一个厨师,两个厨师能炒一样的菜,这两个厨师的关系,就是集群。
为了让厨师专心炒菜,把菜做到极致,又请了一个配菜师负责切菜,备菜,厨师和配菜师的关系是分布式,一个配菜师也忙不过来了,又请了个配菜师,两个配菜师关系是集群。

分布式是指多个系统协同合作完成一个特定任务的系统。
分布式是解决中心化管理的问题,把所有的任务叠加到一个节点处理,太慢了。
所以把一个大问题拆分为多个小的问题,并分别解决,最终协同合作。分布式的主要工作是分解任务,将职能拆解。

1.集群主要是简单加机器解决问题,对于问题本身不做任何分解;
2.分布式处理必然包含任务分解与答案归并。分布式中某个子任务节点,可由一个集群来代替;集群中任一节点,都是做一个完整的任务。
3.集群和分布式都是由多个节点组成,但是集群之间的通信协调基本不需要;而分布式各个节点的通信协调必不可少。
 4.将一套系统拆分成不同子系统部署在不同服务器上(这叫分布式),然后部署多个相同的子系统在不同的服务器上(这叫集群),部署在不同服务器上的同一个子系统应做负载均衡。

lvs+keepalived 实现负载均衡

文章转载来自: https://www.cnblogs.com/edisonchou/p/4281978.html
当前大多数的互联网系统都使用了服务器集群技术,集群是将相同的服务部署在多台服务器上构成一个集群整体对外提供服务,这些集群可以是Web应用服务集群,也可以是数据库服务集群,还可以是分布缓存服务器集群

在实际应用中,在Web服务器集群之前总会有一台负载均衡服务器,负载均衡设备的任务是作为web服务器流量入口,挑选最合适的一台web服务器,将客户端的请求转发给它处理,实现客户端到真实服务端的透明转发。实现客户端到真实服务端的透明转发。
最近几年很火的[云计算]以及分布式架构,本质上也是将后端服务器作为计算资源,存储资源,由某台管理服务器封装成一个服务对外提供,客户端不需要关心真正提供服务的是哪台机器,在它看来,就好像它面对的是一台拥有近乎无限能力的服务器,而本质上,真正提供服务的,是后端的集群。
负载均衡的类型:
1.负载均衡可以采用硬件设备(例如常听见的F5),也可以采用软件,商用硬件负载设备成本高。
2.软件负载解决的两个核心问题是:选举,转发,其中最著名的是LVS (linux Virtual Server)


LVS 是神马东西
lvs 是 linux virtual server 的简称,也就是linux 虚拟服务器,从linux 2.4内核以后,已经完全内置了lvs的各个功能模块,无需给内核打任何补丁,可以直接使用lvs提供的各种功能。
lvs主要用于服务器集群的负载均衡,它工作在网络层,可以实现高性能,高可用的服务器集群技术。它可把许多低性能的服务器组合在一起形成一个超级服务器。


LVS的体系结构
使用lvs架设的服务器集群有三个部分组成:
1)最前端的负载均衡层,用Load Balancer表示;
2)中间的服务器集群层,用Server Array表示;
3)最底层的数据共享存储层,用shared storage表示;
在用户看来,所有的内部应用都是透明的,用户只是在使用一个虚拟服务器提供的高性能服务。

2.4 LVS负载均衡机制

(1)LVS是四层负载均衡,也就是说建立在OSI模型的第四层——传输层之上,传输层上有我们熟悉的TCP/UDP,LVS支持TCP/UDP的负载均衡。因为LVS是四层负载均衡,因此它相对于其它高层负载均衡的解决办法,比如DNS域名轮流解析、应用层负载的调度、客户端的调度等,它的效率是非常高的。  
(2)LVS的转发主要通过修改IP地址(NAT模式,分为源地址修改SNAT和目标地址修改DNAT)、修改目标MAC(DR模式)来实现。       
PS:
NAT模式转发,修改ip地址, 
DR模式,修改目标mac

NAT(Network Address Translation)是一种外网和内网地址映射的技术。NAT模式下,网络数据报的进出都要经过LVS的处理。LVS需要作为RS(真实服务器)的网关。当包到达LVS时,LVS做目标地址转换(DNAT),将目标IP改为RS的IP。RS接收到包以后,仿佛是客户端直接发给它的一样。RS处理完,返回响应时,源IP是RS IP,目标IP是客户端的IP。这时RS的包通过网关(LVS)中转,LVS会做源地址转换(SNAT),将包的源地址改为VIP,这样,这个包对客户端看起来就仿佛是LVS直接返回给它的。客户端无法感知到后端RS的存在。

DR模式下需要LVS和RS集群绑定同一个VIP(RS通过将VIP绑定在loopback实现),但与NAT的不同点在于:请求由LVS接受,由真实提供服务的服务器(RealServer, RS)直接返回给用户,返回的时候不经过LVS。详细来看,一个请求过来时,LVS只需要将网络帧的MAC地址修改为某一台RS的MAC,该包就会被转发到相应的RS处理,注意此时的源IP和目标IP都没变,LVS只是做了一下移花接木。RS收到LVS转发来的包时,链路层发现MAC是自己的,到上面的网络层,发现IP也是自己的,于是这个包被合法地接受,RS感知不到前面有LVS的存在。而当RS返回响应时,只要直接向源IP(即用户的IP)返回即可,不再经过LVS。

DR模式下需要LVS和RS集群绑定同一个VIP(RS通过将VIP绑定在loopback实现),但与NAT的不同点在于:请求由LVS接受,由真实提供服务的服务器(RealServer, RS)直接返回给用户,返回的时候不经过LVS。详细来看,一个请求过来时,LVS只需要将网络帧的MAC地址修改为某一台RS的MAC,该包就会被转发到相应的RS处理,注意此时的源IP和目标IP都没变,LVS只是做了一下移花接木。RS收到LVS转发来的包时,链路层发现MAC是自己的,到上面的网络层,发现IP也是自己的,于是这个包被合法地接受,RS感知不到前面有LVS的存在。而当RS返回响应时,只要直接向源IP(即用户的IP)返回即可,不再经过LVS。  (3)DR负载均衡模式数据分发过程中不修改IP地址,只修改mac地址,由于实际处理请求的真实物理IP地址和数据请求目的IP地址一致,所以不需要通过负载均衡服务器进行地址转换,可将响应数据包直接返回给用户浏览器,避免负载均衡服务器网卡带宽成为瓶颈。因此,DR模式具有较好的性能,也是目前大型网站使用最广泛的一种负载均衡手段。

三、构建实战:LVS+Keepalived实现负载均衡

3.1 实验结构总览

(1)本次基于VMware Workstation搭建一个四台Linux(CentOS 6.4)系统所构成的一个服务器集群,其中两台负载均衡服务器(一台为主机,另一台为备机),另外两台作为真实的Web服务器(向外部提供http服务,这里仅仅使用了CentOS默认自带的http服务,没有安装其他的类似Tomcat、Jexus服务)。  
(2)本次实验基于DR负载均衡模式,设置了一个VIP(Virtual IP)为192.168.80.200,用户只需要访问这个IP地址即可获得网页服务。其中,负载均衡主机为192.168.80.100,备机为192.168.80.101。
Web服务器A为192.168.80.102,
Web服务器B为192.168.80.103。

3.2 基础准备工作

以下工作针对所有服务器,也就是说要在四台服务器中都要进行配置:  
(1)绑定静态IP地址  命令模式下可以执行setup命令进入设置界面配置静态IP地址;x-window界面下可以右击网络图标配置;配置完成后执行service network restart重新启动网络服务;  
  验证:执行命令ifconfig  
(2)设定主机名  ①修改当前会话中的主机名,执行命令hostname xxxx (这里xxxx为你想要改为的名字)  ②修改配置文件中的主机名,执行命令vi /etc/sysconfig/network (√一般需要进行此步凑才能永久更改主机名)  
  验证:重启系统reboot  
(3)IP地址与主机名的绑定  执行命令vi /etc/hosts,增加一行内容,如下(下面的从节点以你自己的为主,本实验搭建了两个从节点):  
192.168.80.100 lvs-master  
192.168.80.101 lvs-slave  
#下面是本次试验的两个真实服务器节点  
192.168.80.102 lvs-webserver1  
192.168.80.103 lvs-webserver2  
保存后退出  
  验证:ping lvs-master  
(4)关闭防火墙  
①执行关闭防火墙命令:service iptables stop     
  验证:service iptables stauts  
②执行关闭防火墙自动运行命令:chkconfig iptables off  
  验证:chkconfig –list | grep iptables

3.3 配置两台Web服务器

以下操作需要在角色为Web服务器的两台中进行,不需要在负载均衡服务器中进行操作:  
(1)开启http服务  
命令:service httpd start  
补充:chkconfig httpd on –>将httpd设为自启动服务  
(2)在宿主机访问Web网页,并通过FTP工具上传自定义网页:这里上传一个静态网页,并通过更改其中的html来区别两台Web服务器,
以下图所示为例,其中一台显示from 192.168.80.102,而另一台显示from 192.168.80.103;

(3)编辑realserver脚本文件  
①进入指定文件夹:cd /etc/init.d/  
②编辑脚本文件:vim realserver

3.4 配置主负载服务器

(1)安装Keepalived相关包
   yum install -y keepalived  
在CentOS下,通过yum install命令可以很方便地安装软件包,但是前提是你的虚拟机要联网;  
(2)编辑keepalived.conf配置文件  
①进入keepalived.conf所在目录:cd /etc/keepalived  
②首先清除掉keepalived原有配置:> keepalived.conf  
③重新编辑keepalived配置文件:vi keepalived.conf

3.5 配置从负载服务器

从负载服务器与主负载服务器大致相同,只是在keepalived的配置文件中需要改以下两处:  
(1)将state由MASTER改为BACKUP  
(2)将priority由100改为99

3.6 验证性测试

(1)指定请求的均衡转发:因为两个Web服务器的权重都一样,所以会依次转发给两个Web服务器;
(2)Web服务器发生故障时:  
①A发生故障后,只从B获取服务;  
这里模拟192.168.80.102发生故障,暂停其http服务:service httpd stop

再来看看这时从外部访问VIP时,便会只从192.168.80.103获取网页:
LVS是目前广为采用的软件负载均衡解决方案,在一些大型企业级系统及互联网系统中应用。本次,简单地了解了一下LVS,并在Linux下搭建了一个小小的测试环境,借助Keepalived实现了一个最小化的负载均衡测试环境。LVS是一个可以工作在网络第四层的负载均衡软件,因此它相对于Nginx一类工作在第七层的负载均衡软件有着无可比拟的性能优势,而且它还是我国的章文嵩博士(现在阿里的副总裁,淘宝的技术专家)作为创始人发起的,现已经成为Linux内核的组成部分。  
当然,目前流行的LVS解决方案中,在Web服务器端也有采用了Nginx+Tomcat这样的搭配类型,静态文件和动态文件分开进行处理,也不失为一种有效的尝试。在以后的日子里,我还会尝试下在Linux下借助Jexus跑ASP.NET MVC项目,试试.NET项目在Linux下的运行效果


LVS有负载均衡机制,目前支持8种均衡算法2.keepalived除了健康检查外,也具备负载功能,现在他的健康检查功能用的比较多,其负载均衡能力被大部分人忽略了。

nginx负载均衡的几种方式

(1) 轮询

upstream backserver {
      server 192.168.0.1;
      server 192.168.0.2;
}

(2) 加权轮询

upstream backserver {
      server 192.168.0.1 weight=3;
      server 192.168.0.2 weight=7;
}

(3) ip_hash[解决登录态问题]

upstream backserver {
    ip_hash;
    server 192.168.0.1;
    server 192.168.0.2;
}

(4) fair模块[跟踪后端服务器的负载来分发请求]
按后端的响应时间来分配请求,响应时间短的优先分配

upstream backserver {
    server server1;
    server server2;
    fair;
}

(5) check模块[check后端节点检查扩展]
nginx_upstream_check_module (后端服务器健康检测模块)

upstream backserver {
    server server1;
    server server2;
    fair;
    check interval=3000 rise=2 fall=5 timeout=1000 type=http
}

timeout=1000 超时1s即失败
fall=5 检测5次,都失败则标记rs为down
interval=3000 每隔3s检测一次
rise=2 请求2次则标记rs为up
type=http 发送http请求,通过后端的回复包状态来判断后端是否存活

常见高可用高性能高并发解决

  • html静态化,CMS常用的高并发解决方案,需要注意更新策略
  • 图片服务器分离(分担web 服务器i/o负载,为图片服务器设置针对性的缓存方案,减少带宽成本,提高平台的可扩展性,可随时增加图片服务器,提高图片吐吞能力)
  • 数据库分库分表、库表散列,比如用户表,奇偶分离,不同模块不同的数据库表,物理上也好做隔离
  • 缓存kv,redis、memcache组件的使用
  • 镜像
  • 负载均衡(nginx, haproxy, 硬件F5)
  • CDN
  • 服务降级(保证关键节点上的可用)
  • 限流(通过对并发访问请求进行限速或一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率,则可以拒绝服务、排队或等待,nginx的limit_conn模块,limit_req模块)
  • 集群(服务器集群,组件集群[redis等])
  • 分布式(mfs,codis等)
  • 超时重试
  • 隔离(线程隔离,进程隔离,读写隔离,动静隔离,机房隔离)
  • 主备方式:HA使用比较多的是keepalived,它使主机备机对外提供同一个虚拟IP,客户端通过vip进行数据操作,正常期间主机一直对外服务,宕机后vip自动漂移到备机上
  • 主从方式:一主多从,主从之间进行数据同步,当Master宕机后,通过Paxos, Raft从Slave中选举出新的Master继续对外服务,主机恢复后以slave的身份重新加入,读写分离也是其中一个目的