单体应用跟微服务应用的区别是单体应用是有状态的,微服务应用的是无状态的;单体应用向微服务应用的发展的一个重要体现就是将应用的状态从应用实例中转移到第三方中间件中.例如会话信息,传统的Java项目是将会话存储在tomcat等servlet容器中对其他的java应用隔离,这样导致的结果是如果想扩展服务的之后只能扩展单台服务器.而微服务能则将会话技术放到redis等nosql中间件中或者直接存到客户端中(jwt),微服务中的所有实例都可读取到
我认为分布式微服务应用还是无状态的比较好,因为现有的有状态分布式应用技术不成熟,gossip协议会导致羊群响应,导致而且如果数据大的情况下宽带会十分巨大.而现有的微服务解决方案依赖第三方中间件,这些中间件天生支持扩展分布式,让专业的工具做专业的事.如果服务要做到有状态的话每个服务中存储的状态数据需要做到一致(不管请求到达那个实例产生的结果一致),这也需要多分数据冗余,这样的话还不如放在第三方中间件中,像redis,mysql集群分布式方案十分丰富而且用的人也多
其实我们可以在有状态跟无状态之间做折中;我们可以参照java线程内存模型的形式,把第三方中间件当作JVM的主内存,微服务实例当作java线程对于主内存的拷贝,每个java线程只会拷贝自己需要访问的数据,微服务实例可以将数据缓存到guava cache或者ecache等进程级的缓存中;当微服务实例需要访问某个值的时候先去进程级缓存中查找,找不到再到集中式缓存中查找;更新某个值的时候,微服务本身先更新值,再将值更新到集中式缓存中,最好时候mq中间件通知其他的微服务实例更新自己进程中的缓存值,当然这里可以在计算更新值的时候避免缓存击穿事件分布式分布式锁技术
展开