在我的應用程序中有一個列表publisherPostListenerList
,它從RabbitMQ隊列接收實時用戶帖子以發送給訂閱者/消費者。該列表是ApplicationListener
類的屬性,該類監聽pubsub隊列的事件。下面的控制器方法通過基於邏輯推送帖子給訂閱者的getter方法&獲取列表元素。爲集羣環境創建列表
的流程如下
用戶寫入一個後 - >發佈進入DB +隊列 - >從隊列消息列表中的哪個是publisherPostListenerList
被推向用戶的用戶加入。
正如我們所見,publisherPostListenerList
是n個併發請求的共同列表,因爲ApplicationListener
是一個單身人士。對於單個實例的安裝工作正常,但會在羣集環境中失敗,因爲每個節點都會有自己的個人publisherPostListenerList
名單。
我該如何處理這種情況?我不能讓ApplicationListener
類無狀態我需要列表來存儲從隊列中收到的帖子元素。我是否將列表放入分佈式內存緩存中?或者還有其他傳統方式?
ApplicationListener.java
@Component
public class ApplicationEventListener {
private List<Post> publisherPostListenerList = new CopyOnWriteArrayList<Post>();
private static final Logger logger = Logger.getLogger(ApplicationEventListener.class);
@EventListener
public void postSubmissionEventHandler(PostSubmissionEvent event) throws IOException {
Post post = event.getPost();
logger.debug("application published user post received " + post);
publisherPostListenerList.add(post);
}
public List<Post> getPublisherPostListenerList() {
return publisherPostListenerList;
}
public void setPublisherPostListenerList(List<Post> publisherPostListenerList) {
this.publisherPostListenerList = publisherPostListenerList;
}
}
控制器方法用於推動消息發送到訂戶
@RequestMapping(value="/getRealTimeServerPushUserPosts")
public SseEmitter getRealTimeServerPushUserPosts(@RequestParam("userId") int userId){
SseEmitter sseEmitter = new SseEmitter();
CustomUserDetail myUserDetails = currentUserAccessor.getCurrentLoggedInUser();
User loggedInUser=myUserDetails.getUser();
List<Integer> userPublisherIDList = this.userService.loadUserPublisherIdListWhichLoggedInUserFollows(loggedInUser);
List<Post> postList =eventListener.getPublisherPostListenerList();
for(Integer userPublisherId : userPublisherIDList){
for(Post post:postList){
if((userPublisherId.intValue()) == (post.getUser().getUserId().intValue())){
try {
sseEmitter.send(post);
postList.remove(post); //removes the post for all the subscribers as the list acts as a global list.
} catch (IOException e) {
logger.error(e);
}
}
}
}
return sseEmitter;
}
誰將會調用控制器的方法? – developer
我使用的服務器發送的事件推消息發送到客戶端/與loggedInUser – underdog
爲什麼不能ü使用數據庫呢? – developer