隔离是指将系统或资源分开,系统隔离是为了在系统发生故障时,能够限定传播范围和影响范围,即发生故障后不回出现滚雪球效应,从而保证只有出问题的服务不可用,其他服务可用。
线程隔离
主要指线程池隔离,实际使用时,将请求分类,交给不同线程池处理
进程隔离
讲系统拆分成多个子系统来实现物理隔离,使得某一个子系统出现问题时,不会影响到其他子系统
集群隔离
单实例服务无法满足需求,此时需要服务化技术,通过部署多个服务形成服务集群,来提升系统容量。而随着调用方增多,当秒杀服务被刷会影响其他服务稳定性时,应该考虑为秒杀提供单独集群,即服务分组,这样当某一个分组出现问题,不会影响到其他分组。
机房隔离
每个机房有自己服务分组,本机方服务应该只调用机房服务,不跨机房调用。
当其中一个机房发生问题时,可以通过DNS/负载均衡将请求全部切换到另一个机房,或者自动重试其他机房。
读写隔离
通过主从模式将读写分离,读只从Redis集群获取数据,当主Redis集群出现问题时,从Redis集群还是可用的,从而不影响用户访问。
动静隔离
当用户访问结算页时,如果JS/CSS等静态资源也在结算页系统中,很可能由于访问量太大而被打满,因此,应该将动态资源和静态资源分离,一般将静态资源放在CDN上。
爬虫隔离
可能有些系统会由于爬虫访问量太大而导致服务不可用,一种方法可以通过限流解决,另一种方法是将爬虫路由到单独集群,从而保证正常流量可用,爬虫流量尽量可用。
可以通过user-agent过滤,并且可以通过IP访问量来设定阈值(可能会影响到正常用户)
当然,也可以使用IP+Cookie方式,验证码方式。
热点隔离
秒杀抢购属于非常合适热点例子,对于这种热点,能够提前知道,所以可以将秒杀抢购做成独立系统或者进行服务隔离,从而保证秒杀抢购流程出现问题时候,不会影响主流程。
资源隔离
最常见的资源,入磁盘、CPU、网络这些宝贵资源,都存在竞争问题。
例如大数据计算集群,数据库集群应该和应用集群隔离到不同的机房或者机架,实现网络隔离;因为大数据计算或者数据库同步会占用比较大的网络带宽,可能会拥塞网络导致应用相应慢。
还有一些其他隔离术例如:
- 环境隔离:测试环境、预发布环境/灰度环境、正式环境
- 压测隔离:真实数据、压测数据隔离
- AB测试:为不同用户提供不同版本服务
- 缓存隔离:有些系统混用缓存,而有些系统会扔大字节值到redis,造成redis慢查询
- 查询隔离:简单、批量、复杂条件查询分别路由到不同集群
Hystrix
Hystrix是Netflix开源的针对分布式系统的延迟和容错库,目前用来隔离分布式服务故障。主要用来解决以下问题:
- 限制分布式服务的资源使用,某一个调用的服务出现问题不会影响到其他服务调用,使用线程池和型号量隔离
- Hystrix提供了优雅降级机制:超时机制、资源不足降级,降级后可以配合降级接口返回托底数据
- Hystrix也提供熔断器实现,当失败率达到阈值自动触发降级(入网络超时导致失败率高),熔断器会进行快速失败会进行快速恢复
- 还提供缓存、请求合并实现。
具体例子可以参看博主以前文章:https://blog.youkuaiyun.com/anLA_/article/details/80659441
基于Servlet 3 实现请求隔离
Tomcat在收到HTTP请求后,会按照如下流程处理
- 容器负责接受并解析请求为HttpServletRequest
- 然后交给Servlet进行业务处理
- 最后通过HttpServletResponse写出相应
在Servelet2.x中,所有这些处理都是同步进行的,也就是说必须在一个线程中完成。入Tomcat 6
而在Tomcat 7.x中,请求得到了异步化,即由一个线程解析请求,,而解析完成后会讲请求仍到业务队列中由业务线程池进行处理,基于异步化有如下好处:
- 基于NIO能够处理更高并发连接数
- 请求解析和业务处理线程池分离
- 更具业务重要性对业务进行分级,并分级线程池
- 对业务线程池进行监控、运维、降级等处理
Servlet3.0新特性可参看:https://www.ibm.com/developerworks/cn/java/j-lo-servlet30/index.html
参考资料