JAVA执行shell脚本并实时获取输出

之前做文档站点的时候有一个需求,做一个在线部署页面,能够通过页面上点点点就自动部署远程服务器上的服务,并且看到部署日志。简单的思路就是,页面通过websocket连接到java后台,java代码调用shell脚本执行发布操作,获取输出,并通过websocket将输出内容返回页面。

发布于 technology

解决实现类添加了@Transactional注解后,无法获取自定义注解的问题

本文记录了如何反射获取代理类上的注解,场景参考添加了@Transactional注解的实现类。

发布于 technology

通过zookeeper实现主从(Master-slave)竞选

背景为了提高系统的健壮性,我们常常做出多节点负载均衡的设计,通过zookeeper注册和发现可用服务,调用端通过一定的负载均衡策略决定请求哪一个可用服务节点。 然后,在某些情况下,服务的调用并非由客户端发起,而是由这个服务自身发起。比如,一个服务可能存在一些定时任务,每分钟去操作一下数据库之类的。当系统只有一个容器时,不用考虑主从的问题,只管到时间了就执行。但如果系统是分布式的,一个服务可能同时运行在多个容器中,查询类的定时任务没有影响,但是某些定时任务每次只需要执行一次,没有区分主从的情况下,每个容器下的服务都会企图去执行,很可能会造成不可预料的结果。 所以,我们需要达到的目标是,服务能够判断自己是否是Master,如果是,则执行,如果不是,则不执行。同时,如果Master服务掉线(比如宕机了),那么某个容器里的slave服务能够自动升级为Master,并执行Master执行的任务。 基础 Zookeeper客户端可以创建临时节点并保持长连接,当客户端断开连接时,临时节点会被删除 Zookeeper客户端可以监听节点变化 实现 定义一个持久化节点/gzcb/master/services,此节点下的子节点为临时节点,分别代表不同的Master服务 Container_1中的服务AccountService,在启动时,在zookeeper中创建临时节点/gzcb/master/services/AccountService:1.0.0,节点的数据为192.168.99.100:9090。这代表,192.168.99.100:9090这个容器中的AccountService(版本为1.0.0)成功竞选为Master服务。Container_1中维护一个缓存,如果竞选成功,对应service:version置为true,否则置为false; Container_2中的服务AccountService,在启动时,也试图创建临时节点/gzcb/master/services/AccountService:1.0.0,但是会创建失败,返回结果码显示该节点已经存在。所以服务就知道已经有一个Master的AccountService(1.0.0)存在,它竞选失败。 Container_2会保持对该临时节点的监听,如果监听到该零时节点被删除,则试图再次创建(创建临时节点的过程就是竞选master的过程),创建成功,则更新缓存对应service:version为true,否则继续保持监听。 优化不管竞选成功还是失败,可以维护一份Master缓存信息,并保持监听,实时更新。这样,不仅能够自动竞选master,还能够通过修改临时节点数据的方式,手动指定Master。 关键代码

发布于 technology

Java 读取jar包中的资源文件夹

记录将项目打成一个可执行jar包后,如何读取jar包中的资源文件夹。

发布于 technology

SOA异步特性设计稿

使用Java1.8的CompletableFuture特性,给soa框架的前后端添加异步特性。

发布于 technology

CompletableFuture

JAVA1.5开始有个Future类,允许异步返回结果,但是对于Future的Consumer来说,他在获取结果(Future.get())时,还是需要阻塞等待的。JAVA8提供了一个新的类CompletableFuture,更好的支持了异步特性,使用类似于回调方法的方式,使得consumer不需要再阻塞等待。

发布于 technology

Java项目内置Jetty

想要在一个Java项目中自启动一个jetty容器,可以打开站点,显示自定义内容,而不需要引入jetty插件或者Ide支持或者类似tomcat那样启动。并且将项目打成jar包,可以在其他项目中引用。

发布于 technology

使用SimpleEmail发送邮件

记录如何使用java代码中发送邮件。

发布于 technology

简单过滤链的实现思路

模仿SpringMVVC的FilterChain方式,使用过滤链的思路实现功能逻辑。

发布于 technology

使用spring启动httpserver

项目中原本使用的是基于socket的server,后来因为一些原因,需要添加一个http的回调地址,供外部调用,但是总不能修改项目结构,而且只是一个接口需求,不想也不需要重新开个项目丢进服务器,所以直接使用了java自带的HttpServer类,启动一个端口作为http请求的回调地址。

发布于 technology