docker单点kafka扩容
背景
公司为了快速上线,几个月前通过docker镜像 kafka 部署了一台kafka-borker。Dockerfile如下
1 | FROM wurstmeister/kafka:latest |
随着业务的增长,单节点的kafka-broker已经成为一个潜在的可靠性隐患。所以借着N年难得一遇的停机维护,决定把kafka-broker扩容为主备集群模式,提升稳定性,并为日后的分区扩容提供可能(不停服)。
公司为了快速上线,几个月前通过docker镜像 kafka 部署了一台kafka-borker。Dockerfile如下
1 | FROM wurstmeister/kafka:latest |
随着业务的增长,单节点的kafka-broker已经成为一个潜在的可靠性隐患。所以借着N年难得一遇的停机维护,决定把kafka-broker扩容为主备集群模式,提升稳定性,并为日后的分区扩容提供可能(不停服)。
项目地址: https://github.com/wangyuheng/Haro-CMS
最近因为换电脑整理资料的过程中,发现了自己之前写过的一些项目,现在准备拿出来升级一下,构建自己的技术体系。看着三个月前的代码,已经似曾相识了,那三年前的呢?
这个项目是用来做企业展示的简易CMS系统,后台管理员可以编辑展示内容,发布新闻;访问用户可以查看企业信息,并反馈建议。这个系统当时应该熬了几个通宵,因为5000大洋实在太吸引人。。而且还是三个人分。。。人的时间好像是越往后越值钱,现在看可能觉得不值,但还是很感谢熬夜编码的自己。
项目当时考虑了很多:分布式,前后端分离,甚至是saas化,希望根据用户反馈,或者再接到类似的项目,可以进一步完善,但是并没有什么后续。所以项目历史就是一个基于web.xml配置的spring单机应用。
目前将其升级为spring-boot应用,并且为了开发演示方便,开发环境使用了H2数据库。一直觉得,项目不需要修改任何配置就能跑起来很重要。
企业信息展示,分为3个module
新版spring boot已不推荐使用jsp,带来很多不便,如: 不能直接运行java, 需要使用maven spring boot 插件运行。
1 | mvn spring-boot:run |
admin 和 view 只负责业务渲染与鉴权,业务操作放在core中,方便后期进行前后端分离。
生产环境数据库使用mysql,为了方便演示,开发环境使用H2内嵌数据库。
之前的项目基于spring开发,采用web.xml配置。spring-boot通过约定大于配置,极大的简化了这部分工作,但是有时候又会因为不熟悉带来迷茫。明明我没有这个配置,怎么就生效了。。而且jsp又不推荐使用,所以虽然大部分是在删代码,单还是遇到了很多问题。
原项目在mvc-dispatcher-servlet.xml文件中配置
1 | <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> |
spring-boot提供了默认配置prefix = “spring.mvc”,详情可以参看org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties类, 并在org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration类中自动注入。
1 | @Configuration |
所以只需在application.properties中添加配置项
1 | spring.mvc.view.prefix=/WEB-INF/pages/ |
未实现前后端分离的项目,css、js等静态资源仍保存在项目中。spring-boot建议保存在resource/static目录下,并通过spring.resources.static-locations属性设置目录位置,并且需要制定mapping规则。
1 | spring.mvc.static-path-pattern=/static/** |
需要添加tomcat-embed依赖,并且设置servlet初始化。如果使用jsp标签,一般也需要添加jstl依赖。
1 | <dependencies> |
1 | @SpringBootApplication |
需要通过spring-boot maven插件运行。
1 | mvn spring-boot:run |
旧项目中为了提高seo通过servlet-mapping指定请求路径为.html
1 | <servlet> |
spring-boot在org.springframework.boot.autoconfigure.web.ServerProperties提供了servlet相关配置,可以通过application.properties配置
1 | server.servlet.path=*.html |
但是目前希望忽略后缀,即请求index和index.html都可以路由到对应的页面,此时可以通过设置pathmatch属性实现
/** * Whether to use suffix pattern match (".*") when matching patterns to requests. * If enabled a method mapped to "/users" also matches to "/users.*". */
1 | spring.mvc.pathmatch.use-suffix-pattern=true |
为了让程序可以“无痛”运行,在代码中使用了基于内存的H2数据库,生产环境可以考虑mysql等关系型数据库,只需修改对应的配置即可。
需要添加H2依赖,引入驱动。
1 | <dependency> |
在配置文件application.properties中直接配置路径、驱动、以及账户信息
1 | spring.datasource.url=jdbc:h2:mem:~/.h2/haro |
db/schema.sql放置在resource目录下,保存了DDL以及开发环境所需数据。DDL支持情况为标准sql语句,部分工具导出的脚本需要简单修改。在程序启动过程中,会初始化执行,如果有异常,会在控制台中有详细提示。
朋友在一家日企,运维工具老旧,希望增加一款系统告警工具。我提议通过微信企业号(改版为企业微信)或者短信推送告警信息。提出两点要求:
做了第一版demo,定位为通信渠道的http代理。贴出企业微信相关代码,如果有需要的同学可以拿去用,记得点个star就好。
https://github.com/wangyuheng/pharos
因为定位为http代理,并未使用数据库及持久化工具。
代理入口为健康检测工具,出口为企业微信、短信等。同时需要保障和健康检测工具之间的网络通畅。
最近在尝试画图
企业微信相关配置如下
1 | wechat: |
weixin-java-tools已经对微信接口进行了友好的封装,可以通过标签、部门等分组,查询用户标识。配置bean方法如下
1 | package com.crick.business.pharos.config; |
同时也提供了发送消息、已经封装消息的类
1 | package com.crick.business.pharos.service; |
1 | package com.crick.business.pharos.service; |
对外暴露的接口主要提供两个功能
具体实现在service中,restful暴露了http请求接口及swagger接口。并且将首页指向了swagger页面
1 |
|
两种验权方式
通过interceptor实现
1 | public class AuthorInterceptor extends HandlerInterceptorAdapter { |
1 | public class SignInterceptor extends HandlerInterceptorAdapter { |
SHA加密工具封装
1 | public class EncryptUtil { |
如果需要对sign有效期进行校验,需要提供获取服务器时钟的方法,避免因为服务器时间不一致导致的时间差, 此方法可以通过@Anonymous去掉验权操作。
1 | @RestController |
定时用http get 请求确认网络通畅,如果网络连接失败次数超过阈值,报警给系统管理员
通过Scheduled编写定时任务
1 | @Component |
在配置bean中需要注入bean并允许启动调度
1 | @Configuration |
项目写的比较仓促,后续根据实际使用场景进行调整优化。都是站在巨人的肩膀上,利用现成的工具进行拼装。 如果有建议或者希望实现哪些功能,可以留言或者给我提issue https://github.com/wangyuheng/pharos 。
春城无处不飞花,寒食东风御柳斜。
推荐大家吃 青团(艾团), 简直发现了新大陆
keyword 变
2017于我而言,是变化的一年。从东北到江南,从在线教育到互联网金融,工作、生活都经历了很多变动,在这个过程中,努力拥抱变化,提升自己。有提升,也有不足。总结一下这一年的种种:
本文项目已发布到github,后续学习项目也会添加到此工程下,欢迎fork点赞。
https://github.com/wangyuheng/spring-boot-sample
http接口开发过程中的常用场景为,根据提交的表单数据进行格式校验,包括字段长度、数据类型、范围等等。。如果每次都写一堆if…else if… 太傻了,所以java提供了一套标准化校验方案JSR 303,而标准的最佳实践为Hibernate Validator。
一句话为,通过注解对bean进行校验,并返回标准文案。