谈谈京东的服务框架JSF

article/2025/9/14 20:42:00

谈谈京东的服务框架

最近由于在实习期间接触到了京东的自研服务框架JSF,简称“杰夫”,目前我写的一些新功能里面调用的下游接口就是杰夫提供的。现有有很多高效的服务框架,如阿里巴巴的Dubbo配合Apache的ZooKeeper,那么为什么京东却自研了JSF服务框架呢?于是看了看京东的JSF的演化历史,不得不感叹好的架构果然不是一朝一夕就能实现的,都是逐步演变而来的。

一、Dubbo与Zookeeper的组合拳

Dubbo是阿里巴巴开源的一个高性能的服务框架,Dubbo使得应用之间可通过高性能的RPC实现服务的输出和输入功能,而且可以和 Spring框架无缝集成。我们可以看看Dubbo架构路线图:从单一应用架构 → 垂直应用架构 → 分布式服务架构 → 流动计算架构 ,也可以看我的另一篇文章《服务拆分方法论》:

img

从上图可以看出互联网的架构演变经历了单一应用架构、垂直应用架构、分布式服务架构和流动计算架构。服务的粒度越来越细化,多个Tomcat的Servlet之间相互调用,服务治理的尤为重要,所以一个优秀的架构来替我们解决服务之间的调用问题,而且还要保证高可用,甚至是实现负载均衡。于是Dubbo框架就出现了,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册与发现。

下面是Dubbo框架的架构图:

mark

节点说明
Provider暴露服务的服务提供方
Consumer调用远程服务的服务消费方
Registry服务注册与发现的注册中心
Monitor统计服务的调用次数和调用时间的监控中心
Container服务运行容器

先用容器Container,通过Docker来启动我们的服务Provider。Dubbo本身没有使用任何的注册中心,而是用一种直连的方式进行的。但是,实际上很多时候都是使用 Dubbo + Zookeeper 的方式,使用 zookeeper 作为注册中心,服务调用方Comsumer就会去注册中心去订阅Subscribe相关服务。注册中心会异步的方式将消费者需要的服务的地址列表推送Notify给你。消费者就会将整个地址列表缓存在本地,当业务需求到来时,就会使用地址列表里的地址去请求相关的服务程序。至于Monitor顾名思义就是监视器的含义,消费者和提供者会定时将服务的调用次数和被调用的次数发送给监视器。关于Dubbo和Zookeeper的使用案例在此就不介绍了,可以参考《Dubbo一篇文章就够了:从入门到实战》。

二、Zookeeper适合作为注册中心吗

当我们提出“Zookeeper作为注册中心合适吗”这个问题的时候,首先考虑的是具体使用场景,我想说的是,在京东,Zookeeper真的不合适!

关于服务注册中心重要性不必多说,注册中心相当于是服务提供者和服务调用者之间的引路人,在服务治理中的作用极为重要,注册中心必须必须必须是高可用的,拥有极强的稳定性。那么如何选择服务器注册中心呢?下面列出一些作为注册中心基本要考量点:

  • 服务注册:接收注册信息的方式
  • 服务订阅:返回订阅信息的方式,推还是拉
  • 状态检测:检测服务端存活状态

状态检测尤其重要,因为这个要是检测不准确会误判,导致严重后果,例如Zookeeper是强一致性的,Zookeeper根据服务端注册的临时节点进行状态检测,如果服务端和Zookeeper之间的网络闪断,导致Zookeeper认为服务端已经死了,从而摘掉这个节点;但是其实客户端和服务端直接的网络是好的,这样就有可能把节点全部摘掉,导致无可用节点。

如果是从开源框架里面选择,那么还需要考量:

  • 成熟度:包括学习成本,社区热度,文档数(盲目追求的不一定是最适合)
  • 维护成本:注册中心维护
  • 数据结构:是否能快速定位结果,是否能遍历
  • 性能和稳定性
  • CAP原则:CP(关注一致性)还是AP(关注可用性)

下面比较一下我知道的两个注册中心

 ZooKeeperEureka
一致性强一致性弱一致性
数据结构TreeK/V
通讯协议TCPHTTP
客户端ZKClientEureka-client
CAP原则CPAP

注册中心的选型总结:

  • 规模小选择CP,RPC框架可以直接接入数据源
  • 规模大选择AP, RPC框架不可以直接接入数据源
  • 存在跨机房,跨地域的尽量不要选有强一致性协议的注册中心
  • RPC框架必须要有注册中心不可用的容灾策略
  • 服务状态检测十分重要

说完了注册中心选型和特点后,我们再来分析Zookeeper是否在适合在京东作为服务注册中心,答案是不适合。Zookeeper在大流量场景下不适合作为注册中心,因为Zookeeper不是为高可用性设计的。

由于要跨机房容灾,很多系统实际上是需要跨机房部署的。出于性价比的考虑我们通常会让多个机房同时工作,而不会搭建N倍的冗余。也就是说单个机房肯定撑不住全流量。由于Zookeeper集群只能有一个master节点,因此一旦机房之间连接出现故障,Zookeeper master就只能照顾一个机房,其他机房运行的业务模块由于没有master都只能停掉。于是所有流量集中到有master的那个机房,于是系统宕机。 这是就是京东在2015年的双十一注册中心挂掉的根本原因。后端容器服务重启以后之前缓存的服务地址列表丢失,服务无法调用。而且Zookeeper没有动态水平扩展的能力,Zookeeper作为注册中心称为了双十一这种高并发场景下的瓶颈。

即使是在同一个机房里面,由于网段的不同,在调整机房交换机的时候偶尔也会发生网段隔离的情况。实际上机房每个月基本上都会发生短暂的网络隔离之类的子网段调整。在那个时刻Zookeeper将处于不可用状态。如果整个业务系统基于Zookeeper(比如要求每个业务请求都先去Zookeeper获取业务系统的master地址),则系统的可用性将非常脆弱。由于Zookeeper对于网络隔离的极度敏感,导致Zookeeper对于网络的任何风吹草动都会做出激烈反应。这使得Zookeeper的服务失效时间比较多,Zookeeper的不可用将导致整个系统的不可用。

三、理想的服务框架是什么样

mark

接口文档管理

提供一个接口文档管理以及接口查询的入口,可以是一个公共的WIKI,也可以是独立的系统,等等。这里可以定义接口的文档,包括接口描述,方法定义,字段定义。可以定义接口的SLA,包括支持的并发数,建议配置是什么。还有就是接口的负责人等一些查询的入口。

配置中心

提供一个配置管理的地方,这里说的配置主要指的是服务相关的一些配置。配置包括分组配置、路由策略、黑白名单、降级开关、限流信息、超时时间、重试次数等等,任何可以动态变更的所有数据。这样服务提供者和服务调用者可以不需要重启自己的应用,直接进行配置的变更。配置中心可以独立于注册中心,也可以和注册中心合并。

监控中心

监控服务关注接口维度,实例(例如所在JVM实例)维度的数据。RPC框架可以定时上报调用次数,耗时,异常等信息。监控中心可以统计出服务质量信息,也可以进行监控报警。

分布式跟踪

区别于监控中心,以调用链的模式对服务进行。RPC框架作为分布式跟踪系统的一个天然埋点,可以很好的进行一个数据输出。

服务治理

我这边列了常见的服务治理功能,例如:

  • 服务路由:

    • 权重:例如机器配置高的权重高,机器配置低的权重低;
    • IP路由:例如某几台机器只能调某几台机器;
    • 分组路由:例如自动根据配置调某个分组;
    • 参数路由:例如根据方法名进行读写分类,或者根据参数走不同的节点;
    • 机房路由:例如只走同机房,或者同机房优先。
  • 调用授权:

    • 应用授权:只有授权后的应用才能调这组服务
    • token:只有token对的调这组服务
    • 黑白名单:只有名单允许的才能调这组服务
  • 动态分组:

    • 服务端切分组:可以根据分组的情况,对服务提供者进行一个动态的分组调度;
    • 客户端切分组:可以对调用者进行一个分组调度。
  • 调用限流:

    • 服务端限流:服务端基于令牌桶或者漏桶模型进行限流;
    • 客户端限流:根据客户端的标识,进行调用次数限流。
  • 灰度部署:

    • 灰度上线:先启动,验证后在提供服务;
    • 预发标识:表示该服务为预发布服务;
    • 接口测试:方便的提供接口自动化功能测试功能。
  • 服务降级:

    • Mock:出现异常或者测试情况下,返回Mock数据;

    • 熔断:客户端超时或者服务端超时;

    • 拒绝服务:服务端压力大时,自动拒绝服务,保护自己。

      网关

RPC框架大部分场景都是自己调用的,什么时候会需要一个网关呢?

网关可以提供如下功能:

  • 统一的鉴权服务;
  • 限流服务;
  • 协议转换:外部协议转统一内部协议;
  • Mock:服务测试,降级等;
  • 其它一些统一处理逻辑(例如请求解析,响应包装)。

四、京东的JSF迭代

JSF雏形——ASF

JSF早期叫做ASF,当时的选择如下:

  • RPC框架:基于dubbo2.3.2做配置扩展,以及功能扩展包括:rest(resteasy)、webservice(cxf)、kryo/thrift序列化、调用压缩等;
  • 注册中心:Zookeeper,RPC框架直接接入数据源;
  • 监控中心:监控服务+HBase;
  • 管理平台:读取Zookeeper做管理平台,提供基本的上下线、黑白名单等功能。

现在的JSF构成

目前的JSF几乎是全部自研

  • RPC框架:轻量级,更佳的性能,兼容旧版本协议;
  • 注册中心:基于DB作为数据源,前置Index服务;支持十倍接入量;部分逻辑放在注册中心减少客户端负担;
  • 监控中心:监控Proxy服务+InfluxDB(2015后改为ElasticSearch);
  • 管理端:基于DB,功能更强大,提供完善的服务治理管理功能;打通京东应用管理平台,提供应用依赖关系梳理;
  • HTTP网关:基于Netty,支持跨语言调用。

目前的JSF是基于DB做的数据最终一致,也就是AP系统。注册中心主要实现的就是服务列表的注册订阅推送,服务配置的获取下发,服务状态的实时查看等功能。注册中心节点是无状态的,可水平扩展的。整个注册中心集群下的所有注册中心几点都是等价的。

JSF优化与特点

  • 引入Index服务概念:该服务就是一个最简单HTTP的服务,用于找注册中心节点(同机房或者压力最小或者其它特定场景),可以认为是不会挂的服务,RPC框架会优先连该服务拿注册中心地址,这样子的好处是注册中心地址变化后,RPC框架不用修改任何设置;

  • 注册中心内存有服务列表全量缓存,连不上数据库也保证可读;

  • 数据库的数据结构更适合各种维度展示、过滤、分析等,例如根据分组/IP/应用/机房等不同维度;

  • 注册中心就是个JSF服务,监控到压力大即可进行动态水平扩展,不会出现2015年双十一那样的事故了;

  • 服务列表推送逻辑改进:例如原来100个Provider,现在加1个节点,之前的SAF是需要下发101个节点,自己判断加了哪个节点,进行长链接建立;现在的改进是:修改为下发一个add事件,告知RPC框架加了1个节点,RPC框架进行长链接建立;这样做大大减少了推送的数据量;

  • 注册中心与RPC框架可各种交互:注册中心和RPC框架是长链接,而且JSF是支持Callback的,注册中心可以调用RPC框架进行服务列表变化之外的操作;例如查看状态,查看配置,配置下发等。


http://chatgpt.dhexx.cn/article/mO2QfKKP.shtml

相关文章

JSF 转换与验证

在本文中,我们将介绍 JSF 转换和验证框架的概念,它比您所想的要容易使用得多,也灵活得多。 首先我们将介绍应用于 JSF 生命周期的转换和验证过程,然后展示一个简单的 JSF 应用程序中的默认转换和验证过程。接着将展示如何创建和插…

JSF----------基础知识初解

初次学习JSF,对其基础进行了一些学习与整理。 JSF(JavaServer Faces)它是一个基于服务器端组件的用户界面框架。 它用于开发Web应用程序。 它提供了一个定义良好的编程模型,由丰富的API和标签库组成。最新版本JSF 2使用Facelets作为其默认模板系统。 它是用Java编写…

JSF详解

1. 结构: a) 结构图: b) 说明:JSF以MVC模式为基础,与Struts不同,JSF的目标是希望以一个与Swing相类似的方式来开发网页,因此,从JSF的结构图当中,他的核心…

JSF框架整理(一)

一、框架简介 JavaServer Faces (JSF) 是一种用于构建Java Web 应用程序的标准框架,它提供了一种以组件为中心的用户界面(UI)构建方法,从而简化了Java服务器端应用程序的开发。 典型的JSF应用程序包含下列部分: 一组J…

JSF简介

JSF简介 一、 什么是 JSF : JavaServer Faces (JSF) 是一种用于构建 Web 应用程序的新标准 Java 框架。它提供了一种以组件为中心来开发 Java Web 用户界面的方法,从而简化了开发。 JavaServer Faces于2004年三月1.0版正式提出,清楚的将Web应…

JSF概述

1. JSF简洁 JSF是一种以组件为中心,遵循MVC设计模式的一种框架。 Web引用程序开发人员划分:网页设计人员应用程序设计人员UI组件设计人员 所有与应用程序都由一个前端控制器(FacesServlet)来处理 2. JSF声明周期 FacesServlet充当用户和JSF应用程序之间的…

ztree项目

思路: 创建一个登陆 登陆上去 就是树 每个是的根节点有他所要展示的内容 表 可以有无数个 主要说的是创建树的表 这个是树的一个表 id 是 节点 name 名字 pid 根节点 url 路径 树的页面 后台通过登陆转的页面 转页面 在前台打印出你想要的数据 前台页面 退出 /*…

ztree使用

官方文档地址 http://www.treejs.cn/v3/main.php#_zTreeInfo 各种参数 http://www.treejs.cn/v3/api.php 简单静态调用 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><link href"https://cdn…

zTree 简介

zTree 是一个依靠 jQuery 实现的多功能 “树插件”。优异的性能、灵活的配置、多种功能的组合是 zTree 最大优点。 zTree 是开源免费的软件&#xff08;MIT 许可证&#xff09;。如果您对 zTree 感兴趣或者愿意资助 zTree 继续发展下去&#xff0c;可以进行捐助。 zTree v3.0 …

ztree 详解

官网:http://www.treejs.cn/v3/demo.php#_101 里面有例子和demo,齐全。 zTree是一个基于jQuery的树形列表生成控件。 切换语言,点击下载,里面有各种demo: 里面各种demo,比博客写的好。 <!DOCTYPE html> <html lang="en"><head><meta ch…

zTree的简单使用1.0

2018/10/10 北京朝阳.冠城大厦17楼 这里是引用 zTree 简介 zTree 是一个依靠 jQuery 实现的多功能 “树插件”。优异的性能、灵活的配置、多种功能的组合是 zTree 最大优点。 zTree 是开源免费的软件&#xff08;MIT 许可证&#xff09;。如果您对 zTree 感兴趣或者愿意资助 zT…

ZTree基本使用及本人详解

文章目录 ZTree树简介简介ZTree的特点练习ztree之前的小建议ZTree文件介绍ZTree的配置介绍 ZTree使用案例需求1&#xff1a;前端初始化数据&#xff08;标准json数据&#xff09;前端代码 需求2&#xff1a;后端查询ztree数据&#xff08;简单JSON数据&#xff09;需求3&#x…

ztree 使用教程

zTree 是一个依靠 jQuery 实现的多功能 “树插件”。被广泛应用在系统的权限管理中&#xff0c;本文讲解zTree的一般应用 zTree 官网 http://www.treejs.cn/v3/main.php#_zTreeInfo 1、zTree 官网下载 ztree 下载好后放到项目相关目录下 2、编写相关代码 引入相关js 、 css …

@PersistenceContext和@Autowired在EntityManager上应用的不同

首先PersistenceContext是jpa专有的注解&#xff0c;而Autowired是spring自带的注释 上方图片的意思就是EntityManager不是线程安全的&#xff0c;当多个请求进来的时候&#xff0c;spring会创建多个线程&#xff0c;而PersistenceContext就是用来为每个线程创建一个EntityMana…

java:spring:注解:@PersistenceContext和@Resource

PersistenceContext private EntityManager em; 注入的是实体管理器&#xff0c;执行持久化操作的&#xff0c;需要配置文件persistence.xml。 注入一堆保存实体类状态的数据结构&#xff0c;针对实体类的不同状态(四种,managedh或detached等)可以做出不同的反应(merge,persis…

@PersistenceContext和@Autowired在EntityManager上应用的区别。

在使用SpringJPA的时候&#xff0c;经常看到如下代码&#xff1a; PersistenceContext private EntityManager entityManager;于是就有些好奇&#xff0c;这个PersistenceContext是几个意思&#xff0c;如果是实体注入的话&#xff0c;统一采用 Autowired不可以吗&#xff1f;…

JAVAEE容器如何管理EntityManager和PersistenceContext

2019独角兽企业重金招聘Python工程师标准>>> 容器托管EntityManager PersistenceContext&#xff0c;存放unitName指向的DataBase对应的EntityBean实例集合&#xff0c;以及对这些实例进行生命周期管理 PersistenceContext( name"entityManagerNa…

An attempt was made to call the method javax.persistence.PersistenceContext.synchronization()

报错 解决办法 1、 2、 3、 4、 5、 别忘了最后点击 Apply 然后在点击ok 重启完事 6、 如果都不行的话 It was loaded from the following location: 就去这个提示下的位置 把它报错的包删除 从新加载Maven即可&#xff01;&#xff01;

Spring各种注解 @PersistenceContext和@Resource @GetMapping、@PostMapping、@PutMapping、@DeleteMapping

这里记录各种spring注解 DataAllArgsConstructorNoArgsConstructorBuilder Data 使用这个注解&#xff0c;就不用再去手写Getter,Setter,equals,canEqual,hasCode,toString等方法了&#xff0c;注解后在编译时会自动加进去。 AllArgsConstructor 使用后添加一个构造函数&…

SpringDataJPA+Hibernate框架源码剖析(六)@PersistenceContext和@Autowired注入EntityManager的区别

SpringDataJPAHibernate框架源码剖析系列文章&#xff1a; SpringDataJPAHibernate框架源码剖析&#xff08;一&#xff09;框架介绍SpringDataJPAHibernate框架源码剖析&#xff08;二&#xff09;框架整合 之 EntityManagerFactory的构建SpringDataJPAHibernate框架源码剖析…