写点什么

系统高可用和用户密码校验

发布于: 2020 年 08 月 26 日
系统高可用和用户密码校验

保障系统稳定高可用

高可用

高可用性,通常来描述一个系统经过专门的设计,从而减少停工时间,而保持其服务的高度可用性。简单的说就是避免因服务器宕机而造成的服务不可用的情况。

衡量高可用

业界一般都是以几个9来表示系统的可用性,9越多就代表可用性越强,例如99.99%的可用,表示全年大约只有53分钟不可用。计算公式如下:



可用性=平均故障间隔/(平均故障间隔 + 故障恢复平均时间)



或者



可用性=1-(故障间隔时间/年度总时间)* 100%

影响系统稳定性的原因

造成系统不稳定的原因主要有以下几个

  • 硬件故障

  • 软件bug

  • 系统发布

  • 并发压力

  • 网络攻击

  • 外部灾害



保障系统高可用的方案

避免单点

高可用的系统首先要避免单点,如果是单点部署的,即使各种优化设计再强,只要主机宕机,一切都凉凉。

避免单点的方案有:

  • 负载均衡

  • 服务集群和失效转移

  • 中间件主备、主从和主主

  • 异地多活、多中心



负载均衡

负载均衡又可分为DNS负载均衡、硬件负载均衡和软件负载均衡。



DNS负载均衡

DNS负载均衡一般用于地理级别的负载均衡,原理就是将域名解析成对应ip,然后将请求转发到对应的机房。



硬件负载均衡

硬件负载均衡是通过独立的硬件设备来实现负载均衡功能,常见的硬件负载均衡器有F5、Array和A10,硬件负载器性能强大但是价格高昂。





软件负载均衡

软件负载均衡是最常见的一种方式,常见的软件负载有Nginx和LVS。Nginx是软件的7层负载均衡,LVS是Linux内核的4层负载均衡。



服务集群

服务集群是指对外提供服务的子系统使用多台主机同时对外提供透明服务,所有服务之间都是互备关系,并分担处理服务请求,一般通过总控节点或集群管理软件(例如zookeeper等)进行高可用的控制。





失效转移

集群模式保障服务节点互备,服务需要设计成无状态,如果有状态那么存有状态的服务节点就变成单点的了,违背了集群的设计初衷。



中间件高可用

主备

主机异常之后通过人工操作将客户端访问切到备机上直到主机恢复,备机数据是主机数据复制备份。

主从

主机可进行读写操作、从机只能进行读操作。主机数据会实时同步到从机上。

主主

两台主机都可以进行读写操作,并且互相进行数据同步。。



异地多活和多中心

异地多活

异地多活就是指不同地理位置上的系统都能够提供业务服务。

异地主要分三类:同城异区、跨城异地和跨国异地。异地多活主要保障保证核心业务,关键是通过多种手段同步数据保证核心数据最终一致性。

多中心

每个中心都是活的,可以实时承担流量,任何一点出问题,都可以直接切掉,由另外一点直接接管。



服务高可用

服务高可用设计主要有以下几个方案

  • 幂等

  • 重试

  • 限流

  • 熔断

  • 降级



幂等

幂等就是保障服务重复调用的结果和一次调用的结果是一致的,一般幂等做法是防止重复提交、Token令牌、乐观锁、分布式锁、建立防重表等。

重试

当调用服务异常时可以设置重试策略,每次重试时间递增,但是需要设置最大重试次数和重试开关,避免对下游系统产生影响

限流

当出现流量高峰使会出现系统资源不够的情况,这时系统不足以应对大量请求,为了保证有限的资源能够正常服务,需要对系统按照预设的规则进行流量限制或功能限制。场景的限流方式有:计数器方法、漏桶算法和令牌桶方法。也可以引入AI做到自适应限流。

熔断

当某服务出现不可用、响应超时或者失败率增加的情况时,为了防止整个系统出现雪崩,熔断器会暂时阻断对该服务的调用。

降级

如果系统出现响应缓慢等状况,可以关闭部分功能,从而释放系统资源,保证核心服务的正常运行。



自动化运维

开发上线流程

版本管理

主流的代码管控流程有两个:主干开发分支发布和分支开发主干发布

  • 主干开发分支发布:代码修改都在主干上,需要发布的时候拉一个分支发布,发现bug则在分支修改,验证完后合并到主干上,主干上的代码是最新的

  • 分支开发主干发布:开发的时候从主干拉一个分支,所有的修改都在分支上,测试通过后合并到主干发布上线,主干上的代码永远都是线上版本



自动化测试

通过自动化测试工具或者自动化脚本对系统进行自动化测试,通过模拟用户操作对开发版本进行全面的验证测试。

自动化部署

自动化部署可以理解为持续集成->持续交付->持续部署。通过持续集成流程完成自动化部署。

预发布验证

通过部署到为对外部开放的线上机器进行线上验证测试,这个未对外开放的线上环境就是预发布环境,在预发布环境可以在与线上相同的环境下进行验证测试

灰度发布

即使经过测试的需求上线也存在出现线上问题的情况,而且当前大型的互联网应用都是庞大的集群部署的,完整的发布一次是一件非常耗时的事情,如果部署过程中发现问题只能眼睁睁的看着,或者发不完之后需要回滚也特别耗时,因此当前大型互联网应用都是先发布一部分主机,观察监控一段时间,如果没问题了再发布一部分,逐步发布,持续几天将整个集群发布完成



监控流程

对线上的用户行为数据监控、服务器性能监控和业务运行数据监控形成一个统一的监控平台,然后通过自动化监控平台对数据监控,如果出现异常及时告警并做一些自动化的补救措施



用户密码验证函数



构建MD5加密方法



/**
* 构建md5加密方法
* @return
*/
static MessageDigest getDigest() {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return md;
}

Hex函数



private static final String HEX_CHARS = "0123456789abcdef";

/**
* 转16进制
* @param bytes
* @return
*/
public static String toHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte value : bytes) {
sb.append(HEX_CHARS.charAt(value >>> 4 & 15));
sb.append(HEX_CHARS.charAt(value & 15));
}
return sb.toString();
}



基础MD5加密和密串Hex处理方法



/**
* 获取经过Hex处理的MD5密串
* @param data
* @return
*/
public static String md5Hex(String data) {
return toHexString(md5(data));
}

/**
* 简单MD5加密
* @param data
* @return
*/
public static byte[] md5(String data) {
return getDigest().digest(data.getBytes());
}



基于用户id和用户密码的加盐加密



/**
* 加盐加密
* @param userId
* @param password
* @return
*/
public static String encrypt(String userId, String password) {
return md5Hex(password + userId);
}



用户密码校验



/**
* 校验密码
* @param password
* @param md5
* @return
*/
public static boolean verify(String userId, String password, String md5) {
return md5Hex(password + userId).equals(md5);
}



测试方法



public static void main(String[] args) {
String userId = "admin";
String password = "abcd1234";
String encryptString = encrypt(userId, password);
System.out.println("加密前:" + password +", 加密后:" + encryptString);
System.out.println(verify(userId, password, encryptString));

System.out.println("加密前:" + password +", 加密后:" + encryptString);
System.out.println(verify(userId, password, encryptString));

password = "abcd9999";
encryptString = encrypt(userId, password);
System.out.println("加密前:" + password +", 加密后:" + encryptString);
System.out.println(verify(userId, password, encryptString));
}



输出结果:



发布于: 2020 年 08 月 26 日阅读数: 50
用户头像

还未添加个人签名 2018.04.29 加入

还未添加个人简介

评论

发布
暂无评论
系统高可用和用户密码校验