长期以来公司架构是基于 Spring 的单体应用,经过这么多年的发展,在企业应用开发层面沉淀颇多,对于新需求也能快速响应。但是由于目前公司业务多元化,单体应用的瓶颈就上来了,比如某个业务需要独立迭代,SAAS 改造的提出等,所以计划将单体升级改造为微服务架构。
目前经过调研,整体升级代价不大,因为虽然是单体应用,但是依然使用多模块开发,各应用天然解耦。但是目前遇到几个比较麻烦的问题,看看有做过相同事情的 hxd 有没有解决方案。
为了降低模块之间的耦合度,系统中大量利用了 Spring 的一些特性,比如 getBeansOfType(),这种模式下,只需要在 A 模块定义好接口,在 B 和 C 模块定义好实现,即可在不同的业务场景下调用不同的实现。这种方式在同一个 Spring 上下中可以轻易获取实现类,但是微服务后就是多个上下文环境,就无法获取到这些实现类了。 伪代码如下:
模块 A:
public interface MessageSender {
/**
* 发送者唯一标识
*/
String key();
/**
* 发送消息
*/
void send(List<Message> messages);
}
@Controller
public class MessageController {
private ApplicationContext ac;
public void sendMessage(String key){
List<MessageSender> messageSenders = ac.getBeansOfType(MessageSender.class);
for(MessageSender sender: messageSenders){
// 获取对应的实例
if(Objects.equals(sender.getKey(), key)){
// 推送消息
sender.send(...);
break;
}
}
}
}
模块 B
@Component
public class EmailMessageSender implements MessageSender {
/**
* 发送者唯一标识
*/
String key(){
return "email":
}
/**
* 发送消息
*/
void send(List<Message> messages){
// 发送邮件
}
}
模块 C
@Component
public class SMSMessageSender implements MessageSender {
/**
* 发送者唯一标识
*/
String key(){
return "sms":
}
/**
* 发送消息
*/
void send(List<Message> messages){
// 发送短信
}
}
利用 Spring 的ApplicationEventPublisher
实现事件推送,目前了解到可以通过对接Spring Cloud Bus
实现跨服务事件推送。现在在我们应用中有同步事件和异步事件,异步事件使用@Async
实现,目前没有了解到Spring Cloud Bus
是否支持同步事件?
模块 A
public class MessageService{
ApplicationEventPublisher publisher;
public void sendMessage(){
publisher.publishEvent(event);
}
}
模块 B
// 模块 B 监听程序
public class EventListener{
@EventListener
public void onEvent(){
// 同步监听
}
@Async
@EventListener
public void onEvent(){
// 异步监听
}
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.