谈谈怎么做【服务隔离】
本文转载自公众号 孤独烟
引言
OK,如下图所示
那显而易见,做服务隔离的目的就是避免服务之间相互影响。毕竟谁也不能说自己的微服务百分百可用,如果不做隔离,一旦一个服务出现了问题,整个系统的稳定性都会受到影响!
因此,做服务隔离是很有必要的。那么怎么隔离呢?
按种类隔离
按用户隔离
OK,接下来开始细说这两种方式!
正文
种类隔离
其实按照服务种类隔离要从两个纬度来说:即服务提供方和服务调用方!
假设我们一个系统有三个服务:订单服务,库存服务,支付服务!有如下调用关系:
OK,我们先明确一点,上面有几个服务扮演服务提供方的角色?
一共是三个:支付服务(给用户提供服务)、库存服务(给支付服务提供服务)、订单服务(给支付服务提供服务)
有几个服务扮演服务调用方的角色?
一共是一个:支付服务(调用订单服务和库存服务)
针对服务提供方这个角度而言,怎么做隔离呢?
很简单,每一个服务乃至其对应的数据库,给一个服务器部署就行!这样某个服务出现了故障,就不会相互影响,达到一种物理层面上的隔离!
什么,你们公司服务器不够?了解一下《微服务为什么一定要用docker》
针对服务调用方这个角度而言,怎么做隔离呢?
OK,先明白一点,服务调用方不做隔离会出现什么情况?如图所示
一个请求过来,占用支付服务中的Tomcat的一个线程。然后,该线程去顺序调用订单服务和库存服务!那么,一旦库存服务出问题了,这个Tomcat的线程就一直卡在那,无法返回!与此同时,页面上源源不断的有请求过来,会把Tomcat里头的线程池资源全部消耗完毕!对于后面的请求,Tomcat就无法响应!
因此,如果不针对被调服务做服务隔离,一个被调服务出问题,就将导致调用方服务不可用!
那怎么隔离呢?
这里介绍一种线程池隔离方式,给每个微服务都初始化出一个线程池,如下图所示,给订单服务和库存服务都初始化出一个线程池,不使用Tomcat线程池中的线程直接调用,而是用相应线程池中的线程去调用!
OK,如果此时库存服务不可用了呢?
库存服务线程池会被迅速塞满,此时后面进来的新请求发现库存服务线程池满啦,于是乎就不去调库存服务,直接返回!如下图所示
ps
:目前业内有信号量隔离和线程池隔离两种隔离方式,这里举的是线程池隔离!
怎么实现呢?
可以了解一下Hytrix、Sentinel、以及Resilience4j如何和你的项目结合起来使用!Resilience4j只提供信号量隔离!
用户隔离
OK,我们先明白一点这里的租户和用户不是一个概念!
用户: 一个环境/系统的一个使用者即该环境/系统的一个用户。
租户:用户从某种粒度上被分到若干组内,每组成为一个租户。
这里的组可以这么理解:用户根据一定的特征去做分组,比如是VIP的一组,不是VIP的一组。又或者北方的用户一组,南方的用户一组。按照自己的业务场景来分组。
那么所谓的用户隔离,就是按照不同的分组形成不同的服务实例。这样某个服务实例挂了,只影响对应分组的用户,而不是全部用户!
有如下三种方式!
方式一:每个租户有独立的服务和独立的数据库
方式二:每个租户有共享的服务和独立的数据库
方式三:每个租户有共享的服务和共享的数据库
下面开始逐个说明
方式一
每个租户有独立的服务和独立的数据库!
这个在生产上一般是这么做,如下所示
如图所示,用户在请求的时候会经过网关!网关根据tenant_id
识别出对应的服务实例,进行转发。至于用什么当网关,我们用的是Zuul。
方式二
每个租户有共享的服务和独立的数据库!
这个在生产上一般是这么做,如下所示
如图所示,用户在请求的时候会经过网关,网关将数据转发给用户服务!用户服务根据tenant_id
确定该操作哪一个数据库!
OK,这个时候大家应该有一个疑问,
在项目代码中,怎么确定该操作的数据库?
好,这个就是ORM框架,动态选择数据源的问题!我以国内流行的hibernate
和mybatis
来进行说明!
(1) hibernate
方式
在4.0版本hibenate
开始支持多租户架构,即对不同租户使用独立数据库!大家可以搜索一个配置,叫hibernate.multiTenancy
。该值有一个value值为
DATABASE:一个租户一个database。
将这项的value值设为DATABASE
后,还需要给hibernate.tenant_identifier_resolver
配置项赋值,即告诉hibernate,如何解析出tenant_id
。以及给hibernate.multi_tenant_connection_provider
配置项赋值,即告诉hibernate如何以租户特有的方式获取数据连接!
ps:
看不懂的童鞋略过,懂hibernate的童鞋自然懂这个配置!
(2) mybatis
方式
mybatis
没提供这种多租户架构的支持!我们必须要扩展AbstractRoutingDataSource
抽象类,实现多数据源切换!
嫌麻烦?
OK,介绍你一个插件叫mybatis plus
可以实现这种动态数据源切换!
API地址都给你贴出来了:
https://mp.baomidou.com/guide/dynamic-datasource.html
ps
:我只能给你点一下思路,自己去查。因为具体如何配置,都可以写一篇文章!我很不爱写这种贴配置的文章,觉得含金量不高,所以大家根据我的思路去实现即可!
方式三
每个租户有共享的服务和共享的数据库!
这个在生产上一般是这么做,如下所示
如图所示,用户在请求的时候会经过网关,网关将数据转发给用户服务!用户服务根据tenant_id
确定操作数据库中的哪一行记录!
老规矩,和你们说一下在ORM中难点在哪!以mybatis为例,所有的sql上都要加一句
AND t.tenant_id = ?
是不是觉得很麻烦?怎么解决呢?
(1) hibernate
方式
利用hibernate filter
配置, OR-Mapping配置文件使用Filter,可以在进行数据查询时自动过滤数据!
如下所示
<class name="User" table="user_tb">//省略<filter name="tenantFilter" condition="tenant_id = :tenantFilterParam" />
</class>
ps:
看不懂的童鞋略过,懂hibernate的童鞋自然懂这个配置!
(2) mybatis
方式
mybatis
中有一个东西叫做自定义Interceptor
,可以拦截出你要执行的sql,然后动态拼上你的租户条件即可!
嫌麻烦?
OK,介绍你一个插件叫mybatis plus
可以实现这种多租户的更改,可以动态的解析出sql,增加上条件!
API地址都给你贴出来了:
https://mp.baomidou.com/guide/tenant.html
总结
本文介绍了服务隔离的分类,以及在生产上具体是怎么做的,希望大家有所收获!
谈谈怎么做【服务隔离】相关推荐
- datatable怎么根据两列分组_谈谈怎么做服务隔离
来源于公众号孤独烟 , 作者孤独烟 引言 OK,如下图所示 那显而易见,做服务隔离的目的就是避免服务之间相互影响.毕竟谁也不能说自己的微服务百分百可用,如果不做隔离,一旦一个服务出现了问题,整个系统的 ...
- 云漫圈 | 谈谈怎么做【服务隔离】
戳蓝字"CSDN云计算"关注我们哦! 转自: 孤独烟 引言 OK,如下图所示 那显而易见,做服务隔离的目的就是避免服务之间相互影响.毕竟谁也不能说自己的微服务百分百可用,如果不做 ...
- 看懂架构设计中的服务隔离
前言 我们在做系统架构设计的时候,经常离不开的一个话题就是进行服务的隔离设计. 那什么是「服务隔离」呢? 顾名思义,它是指将系统按照一定的原则划分为若干个服务模块,各个模块之间相对独立,无强依赖.当有 ...
- 使用Consul做服务发现的若干姿势
作者:波斯码 来源:http://blog.bossma.cn/consul/consul-service-register-and-discovery-style/?hmsr=toutiao.io& ...
- 谈谈京东的服务框架JSF
谈谈京东的服务框架 最近由于在实习期间接触到了京东的自研服务框架JSF,简称"杰夫",目前我写的一些新功能里面调用的下游接口就是杰夫提供的.现有有很多高效的服务框架,如阿里巴巴的D ...
- 谈谈SOA面向服务体系架构的安全问题
谈谈SOA面向服务体系架构的安全问题 本文我们讨论的是面向服务体系架构(SOA)的安全应用.在展开讨论之前,首先让我们来解析面向服务体系架构的实际含义.面向服务体系架构是一种涉及若干以服务为导向的应用 ...
- 一个故事,一段代码告诉你如何使用不同语言(GolangC#)提供相同的能力基于Consul做服务注册与发现
文章目录 引言 什么是微服务 传统服务 微服务 什么是服务注册与服务发现 为什么要使用不同的语言提供相同的服务能力 服务协调器 服务注册 Golang C#(.NetCore3.1) 服务发现 通过H ...
- Hystrix实现服务隔离和降级
背景 在分布式环境下,服务之间有大量的依赖,单个依赖故障时的容灾是个很重要的话题. 伴随着业务复杂性的提高,系统的不断拆分,一个面向用户端的API,其内部的RPC调用层层嵌套,调用链条可能会非常长.这 ...
- 谈谈WIN2K的服务
谈谈WIN2K的服务 创建时间:2002-07-25 文章属性:原创 文章来源: www.opengram.com 文章提交: refdom (refdom_at_263.net) 谈谈WIN2K的服 ...
最新文章
- lstm代码_贼好理解,这个项目教你如何用百行代码搞定各类NLP模型
- 2022年美国大学生数学建模竞赛常见问题汇总
- 数据库脱机和分离的区别
- Angular 内容投影 content projection 的一个问题的单步调试
- Python重现创业板指数行情
- 【javascript高级教程】JavaScript Array(数组) 对象
- HDU1856_More is better
- Codeforces Round #470 Div. 1
- 谈PaaS平台建设:如何应对企业架构多元异构资源的挑战
- linux oracle11.2安装 ins-1010,ARCHLINUX下安装oracle11g
- RabbitMQ各个参数含义
- 有趣的python代码实例_Python之路:200个Python有趣的小例子一网打尽
- AS3文本框的操作,为密码框添加按钮
- centos7 端口3306无法连接问题
- 做了个小工具,可以一键导出所有微信表情包,有趣的表情包,不再只限一个APP使用,【微信表情包吸血鬼】
- ArcGIS 每天一个高级制图技巧:5 lyr和UpdateLayer方法实现样式复用
- c语言long类型转换成string,如何在C ++中将long转换为string?
- APP系列,学院专题讲座图像记录软件推荐
- DSS 部署环境需求清单
- 屏幕尺寸、分辨率、视口笔记