一种多租户系统架构

jopen 5年前

一种多租户系统架构

背景:

去年的时候,因为某些特殊原因,有幸带了一个组,参与了B2B平台的开发。说是B2B平台,因为这套程序开发完了后,可以拿给多个客户使用。客户可以搭建一套具有京东商城风格,那样的网站。然后允许商家在网站上注册,开店,或者卖东西,买东西,网站的用户定位为商家。

在需求分析完后,分为了三个组。

第一个组是商城组,主要负责:商家注册,登录,前端商城主站搭建,商品详情页,搜索页,购物车,下单页,商品评价,仲裁等功能

第二个组是商家组:主要负责商家基本信息维护,商品维护,sku的库存,上下架,订单管理,发货地址管理,会员管理,店铺装修,店铺主站等

第三个组是平台管理,主要负责:类目,品牌管理,商家信息申请审核,店铺审批,商品发布审核,订单结算,商品价格管理,以及主站首页轮播图,楼层等管理。还有就是给我们自己运营人员用的一些功能:比如域名和平台id等功能的管理。

运行时架构图:

nginx:主要做多域名映射,根据域名映射到不同的web Server,比如接受到域名A请求,则路由到web Server1,接受到域名B请求,则路由到web server2

web server:主要是放网页或者web相关的,比如用户登录业务等,客户多变的需求都放到这层实现,比如有些客户在要求自己的网站注册的商家,必须上传运业执照,有些不需要等可变的需求

basic server:后台服务,这层的服务都是共有的,对于每个用户都不变的基础服务都放这层,并且这层做数据库路由,每个域名一个数据库(每个客户一个数据库,做数据隔离,当时个人还不同意,从事后来看,这种架构确实好处比较多,特别是客户以前就有一个网站,然后在往新库里导数据,然后又删新库里的数据时,不担心会把其它客户的数据删掉)。

DB :每个客户一个数据库,做到数据上的逻辑隔离和物理隔离(当时设想每个外部客户1个域名,然后在数据库的每个表里加平台id以区分是那个外部客户的数据,后来架构师力排众议,每个客户1个数据库,做到数据隔离,Basic Server做数据库路由)

如何做数据库路由?

web server根据请求的url,拿到域名,然后查出平台id。basic server中的每个接口,都需要带平台id字段。Web server 调用basic server接口时,传入平台id。然后在basic server的service层,做aop,根据参数里的平台id,找到配置好的平台id和数据库连接信息,把连接信息放入ThreadLocal,包装自己的DataSource,在DataSource里获得数据库连接时,用ThreadLocal里的数据库连接信息,获得数据库连接,方法执行完,清楚数据库连接(这里曾出现过小问题,service嵌套套用的时候,里面service方法退出清楚数据库连接,导致外面service在操作数据库时,拿不到连接信息而报错,后来增加了一个调用层次计数)