关于 hybris 在 kubernetes 集群中部署的一点感想

Submitted by Lizhe on Thu, 09/19/2019 - 08:44

 

从4月份开始着手搭建这套环境已经有半年了,幸亏我有两只手,要不还真不够用

one hand 。。。the other hand 。。。

跟我一开始想的一样,hybris 这种安装完成 就变成几个G 大小的
传统java 应用确实不太适合在 容器编排工具上使用,不是说它不能用,而是,它完全享受不到容器化的好处。

1. 镜像太大,无法拆分

首先,现在的结构里我们可以把hybris拆分成3个镜像(当然每个镜像还是很大)

hybris、solr、mysql 都可以独立成为镜像,
solr 和 mysql 本身都可以做成集群的,分布式也很容易,
mysql 分布式太麻烦或者吞吐量不够的话你还可以花钱解决问题,选择一些和 mysql 兼容的云数据库比如 RDS 什么的,同时也可以解决 数据安全和备份的问题。

但是 hybris,理想状态下,sap一直宣称 hybris 是基于 模块的,addon 什么的,说它易于扩展,方便二次开发,可复用

但是实际上,每个 OOTB 原生功能的addon都不能独立以微服务的方式运行,甚至如果你基于addon的模式进行开发,你的自定义addon也无法以微服务的形式运行。

不仅仅是addon,连  搜索、订单、付款之类的独立服务 也无法拆分,这就造成了一个结果,在容器编排工具环境下,hybris 实例也必需运行在 一个tomcat下,只能做成一个镜像。

 

2. 无法套用 redis 的 session 管理模型

这个问题每次跟tony老师(我项目组里的资深级hybris老专家,资深到全国可能找不出第二个了,当然是他自己说的,不过我真信了)讨论的时候tony老师都讳莫如深的微微一笑(卿不倾城我不 jidao)

这事得从在东京那次我尝试开始把 hybris集群化开始说起,当时我手里已经有了可用的 hybris 镜像,而且外围系统已经构筑完毕,在我的概念里,我只需要把 hybris 运行环境——我的tomcat做一下克隆,然后把 session管理器替换成基于 redis 的就ok了,说干就干 然后使用helm 我轻松得到了一个可用的 redis 集群,替换了 session manager 类包,spring session 配置之后,我甚至可以看到我的redis中得到了session值

然后我给Jon发了一条消息说,我已经看见session存到redis里了,Jon 贱贱的 (我觉得应该是这个表情)回了一句

try backoffice ...

然后果然, backoffice 崩了,前端服务登录都没有问题,backoffice为什么会崩。。。去看kibana,发现log里写的是,session中有对象不能序列化,不能序列化。。。好吧我实在没有本事去改hybris源码,然后暂时选择放弃了这种

 

3. 分布式方式太老

官方文档中给出的 hybris ootb cluster 实现是这样的

stick session + 数据库session 备份

HTTP Session Failover

Sessions used by clients that are bound to an individual cluster node, stick with the cluster node. Therefore, the SAP Commerce Cluster uses the so-called sticky sessions. In addition, SAP Commerce offers a session failover mechanism. For more details, see HTTP Session Failover.

 

SAP Commerce session failover is designed with sticky-session load balancing in mind. A load balancer with configured sticky sessions assigns clients to specific cluster nodes. It always forwards requests from the same client to the same server. The server holds the client session cached in memory. A session is a single up-to-date object and there is no need to read it from the database. When the node stops, the load balancer redirects the client requests to another server. That server doesn't have the respective session object in the cache, so it loads it from the database. Lack of session invalidation makes this approach unsuitable for round-robin session load balancing.

20190919173800

 

也就是说,当用户请求进 hybris 之后,负载均衡器会把用户固定在 第一次分配到 的节点上,不支持robbin规则的轮询机制,就更别提基于性能的什么分发规则了,如果这个 节点 宕机了,那么好,它会从数据库里读取对应的session备份,当然仅仅是节点宕机时,session备份才会起作用,所以它倒是不用担心什么吞吐量的问题。

 

4. jgroups 不支持 kubernetes 

hybris 的集群配置信息里并没有关于 master 节点啊, slave 节点 之类的配置

我禁不住产生了这种疑问,它是如何知道自己集群内部的其他机器的,然后我查阅了一下官方文档

20190919054649

 

cluster.broadcast.method.jgroups=de.hybris.platform.cluster.jgroups.JGroupsBroadcastMethod cluster.broadcast.method.jgroups.tcp.bind_addr=12.34.56.78 cluster.broadcast.method.jgroups.tcp.bind_port=7800 cluster.broadcast.method.jgroups.channel.name=hybris-broadcast cluster.broadcast.method.jgroups.configuration=jgroups-udp.xml

 

这个东西是基于 JGroups 实现的,但是我突然想起了这个东西

20190919055737

 

看见了没,this is trully ... 難しい... and ... あたま痛い

 

I have now confirmed that Amazon does not "block" UDP broadcasts... but rather Amazon does not "support" UDP broadcasts.

 

然后我把这东西改成了 基于 tcp 的,然后发现集群中的 instances 仍然无法互相感知

故事的结局是这样的。。。1808版本压根不支持 kubernetes 。。。

要更新到 1905版本,这个暂时完全脱离我的控制了,需要整体评估之后再做决定了

20190919060646

 

5. 关于 sap cloud 的疑问

在 sap cloud 上,1808版本确实是以集群方式运行的,但是不知道他们是怎么实现的,sap cloud 底层是

kubernetes + azure ,难道 azure 和 aws 不同?

 

20190919061441