服务稳定、高可用

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 64.0px; font: 48.0px "PingFang SC Semibold"; color: #6c6c6c }
p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; text-indent: 59.5px; line-height: 18.0px; font: 26.7px "Songti SC"; color: #6c6c6c }
p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; text-indent: 59.5px; line-height: 18.0px; font: 26.7px "Songti SC"; color: #6c6c6c; min-height: 37.0px }
p.p4 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 49.0px; font: 37.3px "PingFang SC Semibold"; color: #6c6c6c }
p.p5 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px }
p.p6 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 16.0px; font: 12.0px "PingFang SC"; color: #ffffff }
p.p7 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 55.0px; font: 48.0px "PingFang SC"; color: #6c6c6c }
p.p8 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 12.0px "PingFang SC"; color: #000000 }
p.p9 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 55.0px; font: 48.0px "PingFang SC Semibold"; color: #6c6c6c }
p.p10 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 64.0px; font: 53.3px Helvetica; color: #000000 }
p.p11 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 12.0px "PingFang SC"; color: #6c6c6c }
p.p12 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 16.0px; font: 12.0px Times; color: #000000; min-height: 14.0px }
p.p13 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 12.0px Helvetica; color: #000000 }
p.p14 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 12.0px Times; color: #000000; min-height: 14.0px }
p.p15 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 55.0px; font: 48.0px Arial; color: #6c6c6c }
p.p16 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 64.0px; font: 12.0px Times; color: #000000; min-height: 14.0px }
p.p17 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.4px; font: 42.7px "PingFang SC"; color: #959595 }
p.p18 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 21.0px; font: 17.3px Helvetica; color: #000000 }
p.p19 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 21.0px; font: 17.3px "PingFang SC"; color: #000000 }
p.p20 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 19.0px; font: 17.3px "PingFang SC"; color: #000000 }
p.p21 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 19.0px; font: 12.0px Times; color: #000000; min-height: 14.0px }
p.p22 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Times; color: #000000; min-height: 14.0px }
span.s1 { font: 48.0px "PingFang SC" }
span.s2 { }
span.s3 { font: 26.7px Times }
span.s4 { font: 37.3px "PingFang SC" }
span.s5 { font: 48.0px Arial }
span.s6 { font: 12.0px "Lucida Grande" }
span.s7 { color: #1d1d1d }
span.s8 { font: 12.0px Helvetica }
span.s9 { font: 12.0px "PingFang SC" }
span.s10 { font: 42.7px Arial }
span.s11 { font: 17.3px "PingFang SC" }
span.s12 { font: 17.3px Helvetica }
span.s13 { font: 17.3px "PingFang SC"; text-decoration: underline; color: #0000e9 }
span.s14 { font: 17.3px Helvetica; text-decoration: underline; color: #0000e9 }

服务的稳定性对业务的进行极其重要的;

如果我们自己是一个普通用户,要访问某个网站,但这个网站一个页面的打开你要等十来秒甚至几十秒的时间,请问你还有看下去的欲望吗? 服务的稳定性及响应速度差会给你的业务带来以下损失:其一,用户很可能因这个问题而选择你的竞争对手;其二,使你的网站或产品的可信度下降;第三,从SEO的角度来看对搜索引擎极度不友好。说一个案例吧,在聚美优品3周年庆抢购活动上,虽然它的前期营销做得非常好,确实吸引了很多用户在那一天去访问他们的网站并产生了大量的订单,但不幸的是那一天因为他们的服务器不堪重负宕机了,很多用户还在网上排队等待。事后用户挂在嘴边的就是“还是淘宝给力,聚美优品就是没淘宝给力,一个活动网站就塌了”,虽然说这不是本质上的问题,但往往用户会认为你不及人家,而且是连带你这个品牌的所有,特别对于一些大品牌。

所以,我们服务必须保证服务稳定、高可用。

如何做到稳定、高可用呢?

我们大部分服务都是如下结构

防范使用方

2.1 服务接口api参数易用性

l参数定义:定义具有明确含义的参数名称,不要出现a、b、x等的参数。

l参数的类型:每一个参数有明确的数据类型,不要全部都是String,而尽量给每一个参数定义不同合适的数据类型,避免api方法的误用和减少数据类型的转换。

l参数的数量:服务接口api中参数个数不宜太多,一般3个左右比较合适,如果个数太多那就建议使用参数类吧

2.2 良好的接口使用说明

l参数有中文:某些情况下我们的接口会传参中文,中文参数就会有编码要求UTF-8,GBK,如果不约束具体的编码,可能接口就会有乱码甚至保存异常。

l无分页:某些业务逻辑中无分页,但默认情况下要返回前N条数据,如果没有说明就会造成使用方的困惑,徒增沟通时间成本。

l有分页:定义好默认一页记录数,还是允许使用方自行定义返回记录数。根据业务场景还是要约束一页记录数,避免数量过大而影响性能。

……

2.3 接口异常处理

明确、详细的异常信息在调试api、快速定位解决问题中十分有用,因此我们必须设计良好的异常信息,以便自己记录和提供给使用方参考。

l参数检验异常

为了服务接口的安全,我们都会把参数做校验及转换。如参数id是整型类型的 id=81 我们就会做整型类型的校验,如果不是整型的就会返回“参数id必须是整型”的提示信息及自定义的错误代码。

l业务逻辑异常

在内部处理业务逻辑时,如果出现异常我们也要记录相应的异常信息及自定义的错误代码,而不能只给使用方提示“服务器发生错误”这样信息。估计看到这样的信息会抓狂,我们的目的是当使用方拿到错误代码对照接口api使用说明就会很快定位到问题所在。

2.4 接口api版本演进或版本控制

随着业务的发展,老的接口api已不能满足新的业务逻辑,此时是改造老的接口还是增加新的接口?如果在老的接口中进行改造来支持新的业务逻辑,但是不得不维护老的业务逻辑,无形中增加工作量和难度。实际中我们可以新增加接口api,老的api和新的api同时提供服务,然后将老的api平滑过度到新的api。

我们可以定义api版本格式如下

/XXX/api/v2/…

2.5 接口api业务功能分级与隔离

对相关的服务或接口区分核心和非核心,并进行隔离部署,避免服务互相影响。

对于服务的依赖区分核心依赖和非核心依赖,在流量突增的情况下,降级非核心依赖。

优雅降级:对于调用超时的非核心服务,可以设定一个阈值,如果调用超时的次数超过这个阈值,便自动将该服务降级。此时服务调用者跳过对该服务的调用,并指定一个休眠的时间点,当时间点过了之后,再次对该服务进行重试,如果服务恢复,则取消降级,否则继续保持该服务的降级状态。

降级一般就是通过系统中的开关机制实现的。

2.6 服务接口api限流

服务接口api的降级和限流都是流量控制的处理策略,同时也是系统的自我保护策略。虽然牺牲了一部分业务功能和高并发量,但换来的系统的可用性。

常用的限流算法:

l漏桶(Leaky Bucket)算法

l令牌桶算法(Token Bucket)

怀疑第三方

3.1 设置合理的超时时间

如果超时就应该断掉请求连接,把业务处理的线程让给别的请求,加快处理同时也减轻了所依赖服务的压力。

3.2 合理的重试机制

需要结合自己的业务以及异常来仔细斟酌是否使用重试机制。比如调用某第三方服务,报了个异常,有些同学就不管三七二十一就直接重试,这样是不对的,比如有些业务返回的异常表示业务逻辑出错,那么你怎么重试结果都是异常;又如有些异常是接口处理超时异常,这个时候就需要结合业务来判断了,有些时候重试往往会给后方服务造成更大压力,起到雪上加霜的效果。

3.3 异步调用服务接口

我们的服务接口中都会穿插着业务逻辑,如果使用httpsyncclient异步调用服务接口数据,此时处理自己的业务逻辑再结合异步返回的数据组织最终的业务数据,从而提高了服务接口处理能力。

3.4 有兜底,制定好业务降级方案

如果第三方服务挂掉怎么办?我们业务也跟着挂掉?显然这不是我们希望看到的结果,如果能制定好降级方案,那将大大提高服务的可靠性。

l对数据做缓存处理

l友好的错误提示

……

做好自己

做好自己是个非常大的话题,从需求分析、架构设计 、代码编写、测试、code review、上线、线上服务运维等阶段都可以重点展开介绍。

这次简单分享下架构设计、代码编写上的几条经验原则。

4.1 单一职责原则

单一职责原则,在我们的需求分析、架构设计、编码等各个阶段都非常有指导意义。

  在需求分析阶段,单一职责原则可以界定我们服务的边界,服务边界如果没界定清楚,各种合理的不合理的需求都接,最后会导致服务出现不可维护、不可扩展、故障不断的悲哀结局。

  对于架构来讲,单一职责也非常重要。比如读写模块放置在一起,导致读服务抖动非常厉害,如果读写分离那将大大提高读服务的稳定性。

  从代码角度上讲,一个类只干一件事情,如果你的类干了多个事情,就要考虑将他分开。这样做的好处是非常清晰,以后修改起来非常方便,对其它代码的影响就很小。再细粒度看类里的方法,一个方法也只干一个事情,即只有一个功能,如果干两件事情,那就把它分开,因为修改一个功能可能会影响到另一个功能。

4.2 控制资源的使用

CPU资源限制

内存资源限制

网络资源限制

磁盘资源限制

4.2.1 cpu资源限制

a)计算算法优化

  如果服务需要进行大量的计算,比如推荐排序服务,那么务必对你的计算算法进行优化。

b)锁

  对于很多服务而言,没有那么多耗费计算资源的算法,但cpu使用率也很高,这个时候需要看看锁的使用情况,建议是如无必要,尽量不用显式使用锁。

c) 习惯问题

  比如写循环的时候,千万要检查看看是否能正确退出,有些时候一不小心,在某些条件下就成为死循环,很著名的案例就是《多线程下HashMap的死循环问题》。比如集合遍历时候使用性能较差的遍历方式、String +检查,如果有超过多个String相加,是否使用StringBuffer.append

d)尽量使用线程池

  通过线程池来限制线程的数目,避免线程过多造成的线程上下文切换的开销。

e)jvm参数调优

  jvm参数也会影响cpu的使用,如《发布或重启线上服务时抖动问题解决方案》。

4.2.2 内存资源限制

a)Jvm参数设置

  通过JVM参数的设置来限制内存使用,jvm参数调优比较靠经验,可以参考《Linux与JVM的内存关系分析》。

b)初始化java集合类大小

  使用java集合类的时候尽量初始化大小,在长连接服务等耗费内存资源的服务中这种优化非常重要;

c)使用内存池/对象池

d)使用线程池的时候一定要设置队列的最大长度

  之前看过好多起故障都是由于队列最大长度没有限制最后导致内存溢出。

e)如果数据较大避免使用本地缓存

  如果数据量较大,可以考虑放置到分布式缓存如redis、tair等,不然gc都可能把自己服务卡死;

f)对缓存数据进行压缩

  比如之前做推荐相关服务时,需要保存用户偏好数据,如果直接保存可能有12G,后来采用短文本压缩算法直接压缩到6G,不过这时一定要考虑好压缩解压缩算法的cpu使用率、效率与压缩率的平衡,一些压缩率很高但是性能很差的算法,也不适合线上实时调用。

  有些时候直接使用probuf来序列化之后保存,这样也能节省内存空间。

g)清楚第三方软件实现细节,精确调优

  在使用第三方软件时,只有清楚细节后才知道怎么节约内存。

4.2.3 网络资源限制

a)减少调用的次数

  减少调用的次数。经常看到有同学在循环里用redis/tair的get,如果意识到这里面的网络开销的话就应该使用批量处理;又如在推荐服务中经常遇到要去多个地方去取数据,一般采用多线程并行去取数据,这个时候不仅耗费cpu资源,也耗费网络资源,一种在实际中常常采用的方法就是先将很多数据离线存储到一块 ,这时候线上服务只要一个请求就能将所有数据获取。

b)减少传输的数据量

  一种方法是压缩后传输,还有一种就是按需传输,比如经常遇到的getData(int id),如果我们返回该id对应的Data所有信息,一来人家不需要,二来数据量传输太大,这个时候可以改为getData(int id, List<String> fields),使用方传输相应的字段过来,服务端只返回使用方需要的字段即可。

4.2.4 磁盘资源限制

打日志要控制量,并定期清理。1)只打印关键的异常日志;2)对日志大小进行监控报警。3)定期对日志进行清理,比如用crontab,每隔几天对日志进行清理;4)打印日志到远端,对于一些比较重要的日志可以直接将日志打印到远端HDFS文件系统里。

原文地址:https://www.cnblogs.com/seattle-xyt/p/10366255.html

时间: 2024-08-30 13:15:18

服务稳定、高可用的相关文章

Centos7+Nginx+Keepalived实现Apache服务的高可用&负载均衡

Centos7+Nginx+Keepalived实现Apache服务的高可用&负载均衡 今天是2017年的第一天,昨天也就是2016年的最后一天,我尝试部署了Centos7+Nginx+Keepalived实现WEB服务的高可用负载均衡服务,终于在2017年的第一天前完成了,所以在此分享给有需要的朋友:说到负载均衡,其实在linux下有很多服务可以实现,比如nginx.haproxy.lvs等服务,当前我们在前面的文章有介绍过了,但是对于高可用服务,我们在linux下最常见也是应用最多的是Kee

Linux HA Cluster高可用服务器集群,所谓的高可用不是主机的高可用,而是服务的高可用。

什么叫高可用:一个服务器down掉的可能性多种多样,任何一个可能坏了都有可能带来风险,而服务器离线通常带来的代价是很大的,尤其是web站点,所以当某一台提供服务的的服务器down掉不至于服务终止的就叫高可用. 什么叫心跳:就是将多台服务器用网络连接起来,而后每一台服务器都不停的将自己依然在线的信息很简短很小的通告给同一个网络中的备用服务器的主机,告诉其实主机自己依然在线,其它服务器收到这个心跳信息就认为本机是在线的,尤其是主服务器. 心跳信息怎么发送,由谁来收,其实就是进程中的通信两台主机是没法

ceph对象存储(rgw)服务、高可用安装配置

ceph对象存储服务.高可用安装配置 简介:    Ceph本质上就是一个rados,利用命令rados就可以访问和使用ceph的对象存储,但作为一个真正产品机的对象存储服务,通常使用的是Restfulapi的方式进行访问和使用.而radosgw其实就是这个作用,安装完radosgw以后,就可以使用api来访问和使用ceph的对象存储服务了.    首先明白一下架构,radosgw其实名副其实,就是rados的一个网关,作用是对外提供对象存储服务.本质上radosgw(其实也是一个命令)和rbd

基于Corosync和Pacemaker实现Web服务的高可用

Corosync+Pacemaker+iscsi+Httpd实现web服务的高可用 一.软件介绍 Corosync实现的是membership和可靠组通信协议 Pacemaker则基于Corosync/Linux-HA实现服务的管理 Corosync包括如下组件:   Totem  protocol   EVS   CPG   CFG   Quorum Extended Virtual  Synchrony算法(EVS)提供两个功能:   组成员列表的同步:   组消息的可靠组播. Pacema

携程呼叫中心异地双活——座席服务的高可用

携程呼叫中心异地双活--座席服务的高可用

使用redis实现程序或者服务的高可用

使用redis实现程序或者服务的高可用,就是将某一程序或服务部署在不同服务器上,或者是跨机房部署,当运行服务的服务器挂了之后,其他服务器上的该服务能立马顶上,这里我简单的使用redis实现这一目的. 思路是: 部署在不同服务器上的相同服务,隔段时间去redis上查下某一个键(自己定义),如果该键不存在,则设置该键的值,可以是自己本服务器的IP,并设置的一个过期时间,然后执行服务的业务逻辑,如果该键存在,查看该键的值是不是自己的IP,如果是,更新该键的过期时间.代码如下: # coding:utf

CentOS 6.5使用Corosync + pacemaker实现httpd服务的高可用

Corosync:它属于OpenAIS(开放式应用接口规范)中的一个项目corosync一版本中本身不具备投票功能,到了corosync 2.0之后引入了votequorum子系统也具备了投票功能了,如果我们用的是1版本的,又需要用到票数做决策时那该如何是好呢:当然,在红帽上把cman + corosync结合起来用,但是早期cman跟pacemaker没法结合起来,如果想用pacemaker又想用投票功能的话,那就把cman当成corosync的插件来用,把cman当成corodync的投票功

02-keepalived实现对nginx服务的高可用(主备)

实验环境:controller3,controller4为后端web服务器,controller1,controller2为nginx负载均衡服务器,用keepalived实现主备模式的高可用 controller1  IP:9.110.187.120 10.1.1.120 controller2  IP:9.110.187.121 10.1.1.121 controller3  IP:10.1.1.122 controller4  IP:10.1.1.123 1.controller3,con

heartbeat双机热备实现Web服务的高可用

防伪码:没有相当程度的孤独是不可能有内心的平和. 1.概述 Heartbeat 项目是 Linux-HA 工程的一个组成部分,它实现了一个高可用集群系统.心跳服务和集群通信是高可用集群的两个关键组件,在 Heartbeat 项目里,由 heartbeat 模块实现了这两个功能. 通过heartbeat,可以将资源从一台已经故障的计算机快速转移到另一台运转的机器上继续提供服务. 官网:http://www.linux-ha.org/wiki/Main_Page 1.1 工作原理 主备模式:通过修改

heartbeat+crm+mysqld+nfs实现MySQL服务的高可用

测试环境: OS:rhel6 web1:192.168.1.111  MariaDB  Heartbeat  hb_gui web2:192.168.1.112  MariaDB  Heartbeat web3:192.168.1.114  NFS  (共享存储) VIP:192.168.1.150 PS:在web1和web2配置mysql和heartbeat服务,在web3上配置共享存储: 一,首先在web3上配置共享存储 1.建立共享存储目录 #mkdir /mydata #vim /etc