Spring Cloud微服务在花椒直播的实践

Stella981
• 阅读 397

Spring Cloud微服务在花椒直播的实践

本文转载自公众号:花椒技术, 点击查看原文

微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。

微服务的概念源于2014年3月Martin Fowler所写的一篇文章“Microservices”。

现状与选择

Spring Cloud微服务在花椒直播的实践

现状

花椒的服务,无论是和前端靠的比较近的:比如H5官网;还是APP服务:比如用户、直播、经济系统、云控等服务,都是使用PHP开发的。选择PHP的原因如下:

  • PHP的开发效率高。无需编译,开发调试速度快。

  • 团队在PHP方面积累的经验丰富:

  • 成熟的轻量级框架:Web框架QFrame,数据库QFrameDB,服务内部调用SDK:PepperClient,异步消息队列SDK:ProcessClient等

  • 丰富的LNMP调优经验。

  • 成熟的持续集成:发布系统。

  • HULK团队提供稳定高效的私有云解决方案:基于LNMP架构下的 Web服务管理:机器管理,Nginx等配置管理,MySQL、Redis等存储服务。

工作中碰到的技术问题:

  • 服务治理代码和业务代码耦合度高,不通用。使用Nginx + Lua + 降级代码。降级代码写到业务代码中,新增降级需要新写代码,没有一套通用降级,治理方案,耦合度高,影响业务稳定性。

  • 团队维护成本高。服务是分模块的,大家各自维护各自的服务,底层没有核心模块,不同服务之间充斥着重复代码,各自为战,复用性不足。举例:错误码很多服务是重叠的。

  • 服务升级的技术成本很大。举例:经济系统虚拟货币服务分库提升支付能力,因没有成熟的组件, 需要人肉手写分库代码,更需要长时间的回归测试,压力测试才能上线。

  • 服务扩容速度慢,需要申请资源,部署,测试,上线。

  • 服务优化,提升单机性能受限框架上限。受限于LNMP每个请求独享一个进行,同步IO的机制而变得艰难,可以选择更换框架为swoole,选择异步Redis的库,这都需要大量的基础调研、测试、业务代码会被改的面目全非,项目周期会冗长。

    整个后端的微服务做到了分拆:用户、直播、消息、经济系统、云控等,项目的开发效率高,但是维护的工作对工程师的能力要求极高,治理、服务扩容、缩容、技术升级等问题还是困难重重,步履维艰。而Java体系的Spring Cloud在服务注册发现、熔断限流、服务网关、分布式配置等一道解决,而不是在PHP方案上自己找开源去拼凑重构,这方面Java更成熟和成体系,而且Java体系在新兴的微服务架构Service Mesh中融合更好。

现有微服务解决方案

阿里

阿里使用Java做为主要开发语言,开源出框架也很多,分布式和微服务框架:Dubbo、 Spring Cloud Alibaba这两个框架 。Dubbo曾经一度停止维护,后来重新维护并开源到apache,Dubbo只能称为服务治理框架但距离系统完善微服务体系还有很多不足;Spring Cloud Alibaba 是基于Spring Cloud开源的一套微服务一站式解决方案,目前是一个孵化项目,它的仓库也位于Spring Cloud孵化器中,很具有发展潜力。

项目地址:

腾讯

腾讯开源微服务框架:Tars是腾讯从2008年到今天一直在使用的后台逻辑层的统一应用框架,它集可扩展协议编解码、高性能RPC通信框架、路由与发现、发布监控、日志统计、配置管理等于一体,但社区的活跃度不怎么高,文档也不够完善。

项目地址:https://github.com/TarsCloud/Tars

华为

华为的ServiceComb框架:HWCloud在2017年6月发布开源的一款微服务框架,集服务注册、发现、通信和微服务治理能力为一体,并默认提供集中化配置,目前已开源到apache,值得关注。

项目地址:https://servicecomb.apache.org

Spring

不用说,写过Java的人都认识,Spring自2003年开源至今,强大的生命力不断更新迭代,Java框架活跃度No1,基本一统Web开发天下,Spring Boot推出后更加赢得广大Java开发者青睐,随后推出的Spring Cloud微服务整套体系,Spring经过十多年的发展已非常成熟,生态也比较完善。

选择

选择Spring Boot 2作为微服务第一步基础,原因如下:

  • 成熟稳定,社区热度极高,相关资料很多,问题方便解决;

  • 极大地提高了开发效率:使用注解、约定优于配置原则,大大减少了Spring Bean的配置文件;

  • 方便部署,项目可独立打成jar包,无需依赖Web容器;

  • 与微服务相关框架方便集成,几个注解搞定注册中心、配置中心等集成;

  • 提供运行时的应用监控,actuator监控健康;

  • 方便集成第三方http、gRPC组件,跨语言与PHP和Go项目交互。

ORM框架选择:

  • 选择MyBatis,相对于Hibernate更轻便灵活,相对Spring JdbcTemplate功能更强大,使用mybatis-generator可以根据表反向生成model,提升开发效率。

Web容器选择:

  • 选择Undertow:

  • Undertow在高负载情况下性能和稳定性要明显优于Tomcat;

  • 比Tomcat更轻便。

开发规范:

  • 选择安装阿里开源的代码规约扫描插件:Alibaba Java Coding Guidelines,能规范大家代码风格,检测潜在的异常,提前发现问题。

最终初步搭配:Spring Boot 2 + MyBatis Undertow作为Web容器打入jar包中。

稳步改进

Spring Cloud微服务在花椒直播的实践

要既保证支持现有业务的推进,又得保证系统稳定,以活动项目作为先锋,先趟一遍坑。

活动项目结构如下:

  • activity-java活动业务包

  • activity-core活动核心包

  • common-core公共包

  • pepper-client花椒client包

  • pepper-statistics花椒统计监控包

  • pepperbus-client花椒消息总线client包

迭代后的现状架构图:

Spring Cloud微服务在花椒直播的实践

优化与改进:

持续集成发布由Jenkins改为GitLab。

使用GitLab优点:

  • 集成Code Review插件,方便代码审核;

  • CI/CD自动发布部署,项目.gitlab-ci.yml文件配置好后,当开发分支合并到测试分支,自动编译打包、运行测试用例、部署到测试环境,正式环境发布、回滚也是轻松在Web界面点击几个按钮完成;

  • 集成Kubernetes。

注册发现服务,选择Euerka/Nacos。

CAP理论指出,一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。由于分区容错性在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡,在此ZooKeeper保证的是CP,而Eureka则是AP,当然后起之秀阿里开源的Nacos,也值得研究考虑。

其它:

  • 使用OpenFeign作为成为一个轻量级REST API客户端,很方便访问其它http接口,加个配置Hystrix和一个熔断实现类就可以实现熔断;

  • 使用SLF4J的MDC生成TraceId为了未来构建全链路监控做基础;

  • 基于注解+ Springel + Redis实现防并发、幂等性等。

展望未来

Spring Cloud微服务在花椒直播的实践

计划中部署如下微服务组件:

  1. 对外Gateway网关;

  2. 注册中心Euerka;

  3. 配置中心;

  4. 日志服务;

  5. 服务治理中心;

  6. Wayne + Kubernetes容器化。

Spring Cloud微服务在花椒直播的实践

Service Mesh(服务网格): 下一代微服务?

什么是Service Mesh?

服务网格(Service Mesh)是致力于解决服务间通讯的基础设施层。它负责在现代云原生应用程序的复杂服务拓扑来可靠地传递请求。实际上,Service Mesh通常是通过一组轻量级网络代理(Sidecar proxy),与应用程序代码部署在一起来实现,而无需感知应用程序本身。

为什么需要Service Mesh?

有了Spring Cloud整套微服务架构,为什么我们还需要Service Mesh?经过上面的介绍不难发现,整个微服务要关注的组件太多了,在从单体应用程序向分布式微服务架构的转型过程中,开发人员和运维人员面临诸多挑战,而且随着规模和复杂性的增长,服务越来越难以理解和管理。如果用TCP协议类比就很恰当,在TCP协议未出来之前,开发人员需要自己考虑服务间数据包的传输、粘包、网络异常重试等问题,网络传输代码与业务代码耦合,而TCP协议出来后,开发者不用关心网络传输具体实现,有更多精力实现自己的业务,网络传输TCP协议就对应服务网格的Sidecar模式,Sidecar模块代理所有非业务功能。

Service Mesh有如下几个特点:

  • 应用程序间通讯的中间层

  • 轻量级网络代理

  • 应用程序无感知

  • 解耦应用程序的重试/超时、监控、追踪和服务发现

细节图:

Spring Cloud微服务在花椒直播的实践

鸟瞰图:

Spring Cloud微服务在花椒直播的实践

Service Mesh相关框架:第一代以Linkerd和Envoy为代表;第二代以Istio和Conduit为代表。

大厂在Service Mesh上的实践

国内大厂已有服务网格的相关实践,蚂蚁金服、华为、腾讯等公司有成熟运营和迭代,这也是将是发展的必然趋势。

Service Mesh实践资料清单:https://www.servicemesher.com/awesome-servicemesh/

**推荐阅读:
**

Spring Cloud中Hystrix、Ribbon及Feign的熔断关系是什么?

Spring Cloud微服务运维神器之Consul Template?

Python写的微服务如何融入Spring Cloud体系?

Spring Cloud微服务接口这么多怎么调试?

Spring Boot集成Flyway实现数据库版本控制?

Spring Cloud微服务如何实现熔断降级?

Spring Cloud微服务如何设计异常处理机制?

Spring Cloud微服务中网关服务是如何实现的?(Zuul篇)

Spring Cloud是怎么运行的?

基于SpringCloud的微服务架构演变史?

Spring Boot到底是怎么运行的,你知道吗?

Spring Cloud微服务在花椒直播的实践

—————END—————

Spring Cloud微服务在花椒直播的实践

识别图片二维码,关注“无敌码农”获取精彩内容

本文分享自微信公众号 - 无敌码农(jiangqiaodege)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Android蓝牙连接汽车OBD设备
//设备连接public class BluetoothConnect implements Runnable {    private static final UUID CONNECT_UUID  UUID.fromString("0000110100001000800000805F9B34FB");
Stella981 Stella981
3年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这