在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
Quick-FixI. 背景说明case1: 程序出bug了在我们的实际工作中,当我们遇到别人反馈代码出问题了吧,怎么返回的数据不对? 当应用持续跑了一段时间之后,这个时候我们的第一个反应基本是确认能复现么?如果能复现,那么调用的姿势是不是对的?如果确认姿势没问题,那么就是请求参数不对了!!! 如果请求参数还没有问题,卧槽,这下完了,真可能有bug了,这下怎么办? 接下来,一般的讨论是在测试环境复现一下,如果能复现,那么开启debug(或者远程debug),一行行调试,相信很快就能搞定了; 但是,最怕的就是但是,测试环境没法复现,至于线上环境才有问题,这下怎么搞? case2: 缓存数据有问题另外一个场景就是为了提升服务性能,缓存基本上会被大量的使用在各个系统之间;有缓存,那么就会有缓存不一致的问题,如果缓存用的是外部的如(redis/memcache)之类的,那么缓存数据的查询和订正,就相对简单了;但是,如果我们使用了内存作为数据的缓存,比如(hashmap, guava),这种时候,我想知道这个内存中的数据怎么办?我想修改这个内存的中的数据怎么办? 3. 小结上面两个场景,归纳一下主要是两个问题
II. 方案设计为了解决上面抛出的两个问题,我们要怎么做呢? 1. 设计如何访问应用中的方法、数据,首先想到的就是反射;通过反射来执行某个实例的方法,或者获取实例的属性值,并没有太多的难度,有问题的是如何做到无侵入,如何与外部通信,如何做到通用 首先我们需要注入一个EndPoint,用于实现应用于外界的通信,这个是一切开始的基本条件,Fixer的Endpoint负责接收外部请求,并将请求转发给内部的解析器,执行应用内服务访问,并将结果输出给外部使用者 上图给出了EndPoint的结构设计,因为目前的java应用,直接以jar方式跑的不太多了,更常见的是将服务跑在其他的容器中,比如我们常见的tomcat应用,Spring应用等;不同的容器,对外暴露的方式不一样,怎么样才可以做到在不同的容器中,进行优雅的支持呢? 接下来请求到应用内之后,首先定位到访问的服务,其次则进行服务调用执行,其实现流程如下 2. 技术从上面的结构设计出发,找到这个项目实现的关键点,然后看下可以怎么实现 a. 服务定位如何通过传入的请求参数来定位需要执行的服务方法,一般来将,应用中提供的服务可以分为两种情况
然后我们主要目标需要集中在第一种方式,不同的应用方式,获取ServiceHolder不一样,让我们自己去全部支持,显然是不太现实的,因此我们需要设计一个方案,让使用者,自己来根据应用中的ServiceHolder,来选择具体的Service方法 这种,就可以通过SPI机制来支持 b. EndPoint支持提供与外部的交互,最常见的方案就是暴露一个http接口,然后接收外部的请求;非web服务怎么办?也可以开一个socket走tcp通信,那么问题来了
所以再具体的实现中,我们需要考虑以下几点
针对上面的问题,具体实现时,会用到下面一些机制
III. 相关博文从设计到实现,下面博文分别进行详细介绍说明 技术文档
使用文档 IV. 使用说明1. 依赖管理首先添加仓库,两种方式,一个是github的release版本的引入,优势是稳定;确定是更新及时问题; <repositories> <repository> <id>jitpack.io</id> <url>https://jitpack.io</url> </repository></repositories> 另一个是我个人的仓库 <repositories> <repository> <id>yihui-maven-repo</id> <url>https://raw.githubusercontent.com/liuyueyi/maven-repository/master/repository</url> </repository></repositories> 2. 引入依赖包根据实际的应用场景,引入对应的依赖包, a. 纯jar应用<dependency> <groupId>com.git.hui.fix</groupId> <artifactId>fix-core</artifactId> <version>1.4.2</version></dependency> 注意事项:
使用姿势如下: curl -X POST -H "Content-Type:application/json" http://127.0.0.1:9999/fixer/call -d '{"service": "CalculateServer", "method": "getCache", "params": ["init"], "type":"static"}' 实例demo: b. 纯Spring应用如我是一个纯Spring应用,没有使用SpringMVC,可以引入 <dependency> <groupId>com.git.hui.fix</groupId> <artifactId>spring-fixer</artifactId> <version>1.4.2</version></dependency> 注意事项: spring-fixer提供了访问Spring容器内bean的服务方式,因此除了获取默认提供的静态类之外,还可以访问bean;
使用姿势如下: # 执行bean的某个方法curl -X POST -H "Content-Type:application/json" http://127.0.0.1:8080/inject-fixer-endpoint/call -d '{"service": "demoBean", "method": "randName"}'# 查看bean的属性值curl -X POST -H "Content-Type:application/json" http://127.0.0.1:8080/inject-fixer-endpoint/call -d '{"service": "demoBean", "field": "name"}'# 执行bean的属性的某个方法curl -X POST -H "Content-Type:application/json" http://127.0.0.1:8080/inject-fixer-endpoint/call -d '{"service": "demoBean", "field": "values", "method":"add", "params": ["autoInsertByQuickFixer!"]}'# 测试静态类的静态成员的方法调用curl -X POST -H "Content-Type:application/json" http://127.0.0.1:9999/fixer/call -d '{"service": "com.git.hui.fix.example.spring.server.StaticBean", "method": "getCache", "params": ["init"], "type":"static"}'# 单例类的使用姿势curl -X POST -H "Content-Type:application/json" http://127.0.0.1:8080/inject-fixer-endpoint/call -d '{"service": "SingletonBean", "method": "getInstance", "secondMethod": "sayHello", "secondParams": ["init"], "type":"static"}' 实例demo: c. SpringMVC应用如是一个SpringMVC应用,可以引入 <dependency> <groupId>com.git.hui.fix</groupId> <artifactId>spring-mvc-fixer</artifactId> <version>1.4.2</version></dependency> 使用说明:
使用姿势&实例:
d. SpringCloud应用如果是一个SpringCloud服务,且开启了 actuator 应用监测,可以引入 <dependency> <groupId>com.git.hui.fix</groupId> <artifactId>spring-cloud-fixer</artifactId> <version>1.4.2</version></dependency> 使用说明:
使用姿势&实例: V. End版本说明v1.1
v1.2
v1.3
v1.4
v1.4.1
v1.4.2
其他拒绝单机,欢迎start或者加好友支持 声明尽信书则不如,已上内容,一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激
扫描关注公众号&博客 打赏码 |
请发表评论