服务器宕机,Root cause of ServletException
两个都是servlet中的
特别是后面的
Servlet failed with Exception
javalangNullPointerException
这种null的错,好好检查
负载均衡器 是基于硬件的
软件的话,在windows平台上面 无成本的是靠服务器群集了 你可以先看看先关的资料 当然服务器时限群集的时候 自然也就有负载均衡的能力了,cdn是为站点加速访问的的技术,主要是通过购买cdn加速服务。
如何进行网站的服务器集群配置?
在今天的互联网时代,网站成为了人们不可或缺的一部分。而为了满足用户的需求,并保证网站的稳定性和可靠性,往往需要对服务器进行配置。其中,服务器集群就是一种常见的配置形式。
什么是服务器集群?
服务器集群是指多台服务器通过互联网或内部网络相互连接,彼此之间共同工作,以提高网站性能和可靠性。通俗来说,就是将多台服务器组合在一起,形成一个高可用性、高伸缩性、高安全性的整体。
为什么需要服务器集群?
在日常生活中,很多时候我们会访问一些热门的网站,比如淘宝、京东等。这些网站每天都面临着数以百万计的访问量和海量的数据请求,因此,单独一台服务器难以承受这样的压力。而服务器集群,则可以将压力分担到多台服务器上,从而保证网站的稳定性和可靠性。
如何进行服务器集群配置?
一般来说,服务器集群的配置需要经过以下几个步骤:
1选购服务器:首先需要购买多台服务器,并根据实际需求选择配置合理的服务器。
2安装操作系统:在服务器上安装适合的操作系统,一般使用Linux服务器最为常见。
3安装负载均衡软件:负载均衡软件可以将用户的请求分配到服务器集群中的不同节点,从而达到均衡负载的效果。常见的负载均衡软件有Nginx、LVS等。
4配置数据共享:数据共享可以保证服务器之间数据的一致性,避免出现数据不一致的情况。常见的数据共享方式有NFS、Samba等。
5配置服务器节点:对于集群中的每个节点,需要进行相应的配置,包括网络、防火墙、SSH等设置。
总结:
服务器集群配置虽然比较复杂,但能够大大提高网站的性能和可靠性。通过合理配置多台服务器,将负载分担到不同的节点上,可以避免服务器单点故障而导致的网站宕机,保证网站的正常运行。如果您也想提高自己网站的稳定性和可靠性,不妨考虑使用服务器集群配置。
宕机的读音是dàng jī,具体释义如下:
表达意思:宕机是计算机术语,在计算机中用dowm来表示把机器停止,转换成汉字就是宕机,也可以理解为死机,服务器不能正常工作了,其中也包括一切服务器出现死机的原因。
宕机指操作系统无法从一个严重系统错误中恢复过来,或系统硬件层面出问题,以致系统长时间无响应,而不得不重新启动计算机的现象。它属于电脑运作的一种正常现象,任何电脑都会出现这种情况。
词性:通常在句中作动词,修饰主语或宾语。
例句
1、我们还将设置一些安全措施,以确保我们的网站不会因为愤怒的吸血鬼黑客活动而宕机。
2、使用监控软件来检测主服务器是否宕机。
3、您还会测试一次有意识的和一次不干净的集群宕机情况,以判断集群的状态能否得到安全保持。
对于多数应用来说,MySQL都是作为最关键的数据存储中心的,所以,如何让MySQL提供HA服务,是我们不得不面对的一个问题。当master当机的时候,我们如何保证数据尽可能的不丢失,如何保证快速的获知master当机并进行相应的故障转移处理,都是需要我们好好思考的。这里,笔者将结合这段时间做的MySQL proxy以及toolsets相关工作,说说我们现阶段以及后续会在项目中采用的MySQL HA方案。
Replication
要保证MySQL数据不丢失,replication是一个很好的解决方案,而MySQL也提供了一套强大的replication机制。只是我们需要知道,为了性能考量,replication是采用的asynchronous模式,也就是写入的数据并不会同步更新到slave上面,如果这时候master当机,我们仍然可能会面临数据丢失的风险。
为了解决这个问题,我们可以使用semi-synchronous replication,semi-synchronous replication的原理很简单,当master处理完一个事务,它会等待至少一个支持semi-synchronous的slave确认收到了该事件并将其写入relay-log之后,才会返回。这样即使master当机,最少也有一个slave获取到了完整的数据。
但是,semi-synchronous并不是100%的保证数据不会丢失,如果master在完成事务并将其发送给slave的时候崩溃,仍然可能造成数据丢失。只是相比于传统的异步复制,semi-synchronous replication能极大地提升数据安全。更为重要的是,它并不慢,MHA的作者都说他们在facebook的生产环境中使用了semi-synchronous(这里),所以我觉得真心没必要担心它的性能问题,除非你的业务量级已经完全超越了facebook或者google。在这篇文章里面已经提到,MySQL 57之后已经使用了Loss-Less Semi-Synchronous replication,所以丢数据的概率已经很小了。
如果真的想完全保证数据不会丢失,现阶段一个比较好的办法就是使用gelera,一个MySQL集群解决方案,它通过同时写三份的策略来保证数据不会丢失。笔者没有任何使用gelera的经验,只是知道业界已经有公司将其用于生产环境中,性能应该也不是问题。但gelera对MySQL代码侵入性较强,可能对某些有代码洁癖的同学来说不合适了:-)
我们还可以使用drbd来实现MySQL数据复制,MySQL官方文档有一篇文档有详细介绍,但笔者并未采用这套方案,MHA的作者写了一些采用drdb的问题,在这里,仅供参考。
在后续的项目中,笔者会优先使用semi-synchronous replication的解决方案,如果数据真的非常重要,则会考虑使用gelera。
Monitor
前面我们说了使用replication机制来保证master当机之后尽可能的数据不丢失,但是我们不能等到master当了几分钟才知道出现问题了。所以一套好的监控工具是必不可少的。
当master当掉之后,monitor能快速的检测到并做后续处理,譬如邮件通知管理员,或者通知守护程序快速进行failover。
通常,对于一个服务的监控,我们采用keepalived或者heartbeat的方式,这样当master当机之后,我们能很方便的切换到备机上面。但他们仍然不能很即时的检测到服务不可用。笔者的公司现阶段使用的是keepalived的方式,但后续笔者更倾向于使用zookeeper来解决整个MySQL集群的monitor以及failover。
对于任何一个MySQL实例,我们都有一个对应的agent程序,agent跟该MySQL实例放到同一台机器上面,并且定时的对MySQL实例发送ping命令检测其可用性,同时该agent通过ephemeral的方式挂载到zookeeper上面。这样,我们可以就能知道MySQL是否当机,主要有以下几种情况:
机器当机,这样MySQL以及agent都会当掉,agent与zookeeper连接自然断开
MySQL当掉,agent发现ping不通,主动断开与zookeeper的连接
Agent当掉,但MySQL未当
上面三种情况,我们都可以认为MySQL机器出现了问题,并且zookeeper能够立即感知。agent与zookeeper断开了连接,zookeeper触发相应的children changed事件,监控到该事件的管控服务就可以做相应的处理。譬如如果是上面前两种情况,管控服务就能自动进行failover,但如果是第三种,则可能不做处理,等待机器上面crontab或者supersivord等相关服务自动重启agent。
使用zookeeper的好处在于它能很方便的对整个集群进行监控,并能即时的获取整个集群的变化信息并触发相应的事件通知感兴趣的服务,同时协调多个服务进行相关处理。而这些是keepalived或者heartbeat做不到或者做起来太麻烦的。
使用zookeeper的问题在于部署起来较为复杂,同时如果进行了failover,如何让应用程序获取到最新的数据库地址也是一个比较麻烦的问题。
对于部署问题,我们要保证一个MySQL搭配一个agent,幸好这年头有了docker,所以真心很简单。而对于第二个数据库地址更改的问题,其实并不是使用了zookeeper才会有的,我们可以通知应用动态更新配置信息,VIP,或者使用proxy来解决。
虽然zookeeper的好处很多,但如果你的业务不复杂,譬如只有一个master,一个slave,zookeeper可能并不是最好的选择,没准keepalived就够了。
Failover
通过monitor,我们可以很方便的进行MySQL监控,同时在MySQL当机之后通知相应的服务做failover处理,假设现在有这样的一个MySQL集群,a为master,b,c为其slave,当a当掉之后,我们需要做failover,那么我们选择b,c中的哪一个作为新的master呢?
原则很简单,哪一个slave拥有最近最多的原master数据,就选哪一个作为新的master。我们可以通过show slave status这个命令来获知哪一个slave拥有最新的数据。我们只需要比较两个关键字段Master_Log_File以及Read_Master_Log_Pos,这两个值代表了slave读取到master哪一个binlog文件的哪一个位置,binlog的索引值越大,同时pos越大,则那一个slave就是能被提升为master。这里我们不讨论多个slave可能会被提升为master的情况。
在前面的例子中,假设b被提升为master了,我们需要将c重新指向新的master b来开始复制。我们通过CHANGE MASTER TO来重新设置c的master,但是我们怎么知道要从b的binlog的哪一个文件,哪一个position开始复制呢?
GTID
为了解决这一个问题,MySQL 56之后引入了GTID的概念,即uuid:gid,uuid为MySQL server的uuid,是全局唯一的,而gid则是一个递增的事务id,通过这两个东西,我们就能唯一标示一个记录到binlog中的事务。使用GTID,我们就能非常方便的进行failover的处理。
仍然是前面的例子,假设b此时读取到的a最后一个GTID为3E11FA47-71CA-11E1-9E33-C80AA9429562:23,而c的为3E11FA47-71CA-11E1-9E33-C80AA9429562:15,当c指向新的master b的时候,我们通过GTID就可以知道,只要在b中的binlog中找到GTID为3E11FA47-71CA-11E1-9E33-C80AA9429562:15这个event,那么c就可以从它的下一个event的位置开始复制了。虽然查找binlog的方式仍然是顺序查找,稍显低效暴力,但比起我们自己去猜测哪一个filename和position,要方便太多了。
google很早也有了一个Global Transaction ID的补丁,不过只是使用的一个递增的整形,LedisDB就借鉴了它的思路来实现failover,只不过google貌似现在也开始逐步迁移到MariaDB上面去了。
MariaDB的GTID实现跟MySQL 56是不一样的,这点其实比较麻烦,对于我的MySQL工具集go-mysql来说,意味着要写两套不同的代码来处理GTID的情况了。后续是否支持MariaDB再看情况吧。
Pseudo GTID
GTID虽然是一个好东西,但是仅限于MySQL 56+,当前仍然有大部分的业务使用的是56之前的版本,笔者的公司就是55的,而这些数据库至少长时间也不会升级到56的。所以我们仍然需要一套好的机制来选择master binlog的filename以及position。
最初,笔者打算研究MHA的实现,它采用的是首先复制relay log来补足缺失的event的方式,但笔者不怎么信任relay log,同时加之MHA采用的是perl,一个让我完全看不懂的语言,所以放弃了继续研究。
幸运的是,笔者遇到了orchestrator这个项目,这真的是一个非常神奇的项目,它采用了一种Pseudo GTID的方式,核心代码就是这个
代码如下:
create database if not exists meta;
drop event if exists metacreate_pseudo_gtid_view_event;
delimiter ;;
create event if not exists
metacreate_pseudo_gtid_view_event
on schedule every 10 second starts current_timestamp
on completion preserve
enable
do
begin
set @pseudo_gtid := uuid();
set @_create_statement := concat('create or replace view metapseudo_gtid_view as select \'', @pseudo_gtid, '\' as pseudo_gtid_unique_val from dual');
PREPARE st FROM @_create_statement;
EXECUTE st;
DEALLOCATE PREPARE st;
end
;;
delimiter ;
set global event_scheduler := 1;
它在MySQL上面创建了一个事件,每隔10s,就将一个uuid写入到一个view里面,而这个是会记录到binlog中的,虽然我们仍然不能像GTID那样直接定位到一个event,但也能定位到一个10s的区间了,这样我们就能在很小的一个区间里面对比两个MySQL的binlog了。
继续上面的例子,假设c最后一次出现uuid的位置为s1,我们在b里面找到该uuid,位置为s2,然后依次对比后续的event,如果不一致,则可能出现了问题,停止复制。当遍历到c最后一个binlog event之后,我们就能得到此时b下一个event对应的filename以及position了,然后让c指向这个位置开始复制。
使用Pseudo GTID需要slave打开log-slave-update的选项,考虑到GTID也必须打开该选项,所以个人感觉完全可以接受。
后续,笔者自己实现的failover工具,将会采用这种Pseudo GTID的方式实现。
在《MySQL High Availability》这本书中,作者使用了另一种GTID的做法,每次commit的时候,需要在一个表里面记录gtid,然后就通过这个gtid来找到对应的位置信息,只是这种方式需要业务MySQL客户端的支持,笔者不很喜欢,就不采用了。
后记
MySQL HA一直是一个水比较深的领域,笔者仅仅列出了一些最近研究的东西,有些相关工具会尽量在go-mysql中实现。
更新
经过一段时间的思考与研究,笔者又有了很多心得与收获,设计的MySQL HA跟先前有了很多不一样的地方。后来发现,自己设计的这套HA方案,跟facebook这篇文章几乎一样,加之最近跟facebook的人聊天听到他们也正在大力实施,所以感觉自己方向是对了。
新的HA,我会完全拥抱GTID,比较这玩意的出现就是为了解决原先replication那一堆问题的,所以我不会考虑非GTID的低版本MySQL了。幸运的是,我们项目已经将MySQL全部升级到56,完全支持GTID了。
不同于fb那篇文章将mysqlbinlog改造支持semi-sync replication协议,我是将go-mysql的replication库支持semi-sync replication协议,这样就能实时的将MySQL的binlog同步到一台机器上面。这可能就是我和fb方案的唯一区别了。
只同步binlog速度铁定比原生slave要快,毕竟少了执行binlog里面event的过程了,而另外真正的slaves,我们仍然使用最原始的同步方式,不使用semi-sync replication。然后我们通过MHA监控整个集群以及进行故障转移处理。
以前我总认为MHA不好理解,但其实这是一个非常强大的工具,而且真正看perl,发现也还是看的懂得。MHA已经被很多公司用于生产环境,经受了检验,直接使用绝对比自己写一个要划算。所以后续我也不会考虑zookeeper,考虑自己写agent了。
虽然这是基于2台服务器的MySQL集群,但也必须有额外的第三台服务器作为管理节点,但这台服务器可以在集群启动完成后关闭。同时需要注意的是并不推荐在集群启动完成后关闭作为管理节点的服务器。尽管理论上可以建立基于只有2台服务器的MySQL集群,但是这样的架构,一旦一台服务器宕机之后集群就无法继续正常工作了,这样也就失去了集群的意义了。出于这个原因,就需要有第三台服务器作为管理节点运行。
推荐两种:
1jvm监控,本地一个守护进程,连接本地所有java进程,获取jvm信息,上报给你的监控中心,可以获取cpu,内存,gc、线程数、cpu使用等信息,这个能判断jvm信息
2做一个公共的框架,提供方法调用频率汇报或者自己心跳汇报,这个是业务层次的心跳,是相对更准确的
一般大的集群,都离不开这两种监控
问题:
部分主机宕机后,CDH集群启动成功,但是有某些主机提示“无法找到主机的NTP 服务,或该服务未响应时钟偏差请求”
解决步骤:
1先同步服务器时钟
执行命令:
service ntpd stop 停止ntp服务
ntpdate 主机ip 同步主机时钟
service ntpd start 启动ntp服务
service ntpd status 查看服务启动情况
ntpq -pn 查看同步的服务器IP
ntpstat 查看同步结果
2在CDH界面停止主机上的角色
3进入该主机的CDH安装目录执行 /cloudera-scm-agent restart (即需要在问题主机上重启cloudera-scm-agent服务)
目录在 etc/initd下
4等待CDH界面刷新,问题解决,大概等3 5分钟就看不到时钟偏差问题了。
解决思路:
1同步服务器时钟是为了确定是否是ntp服务本身的问题。
2发现服务器时钟没有问题,所以不是ntp服务本身的问题。
其中这句话说,如果该命令失败、NTP 未与服务器同步,或主机的 NTP 后台程序未运行或无法联系,该测试将返回运行状况“不良”。
所以可能是CDH集群本身没有接收到时间同步服务器的结果,于是执行重启agent的命令。至此问题解决!
0条评论