In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
In this issue, the editor will bring you about how to build a distributed second kill system for WebSocket push notification. The article is rich in content and analyzed and described from a professional point of view. I hope you can get something after reading this article.
Preface
In the later stage of the second kill architecture, we implemented the rush purchase logic in the form of a message queue, so we have thrown such a question before: after the message queue asynchronously processes each user request, how to inform the corresponding user that the second kill is successful?
Scene mapping
First of all, let's cite a common example in our daily life: when we go to a bank to do business, we usually choose the relevant business to print a number paper, and then we can sit on the bench and play with our mobile phone, waiting to be called by the trumpet. When the trumpet calls out the number you have, you can take the numbering paper to the counter to handle your own business.
Here, suppose that when we take the numbering paper, according to the queuing situation during the time period, the bank will give a more humane reminder to the user: there are more people in the queue, do you want to continue to wait? If not, we can deal with it another time.
As a result, we map the life scenario to the real second kill business logic:
We can compare the counter to a logical unit of order processing for goods.
Getting the numbering paper means that you enter the corresponding commodity processing queue.
The request for ranking paper is returned directly to the front desk, prompting the user to snap up the goods.
After the ranking paper enters the queue, wait for the commodity business processing logic
When the trumpet calls its own ranking number, it is equivalent to the server notifying the user that the second kill is successful. At this time, the payment logic can be carried out.
Those students who can not get the ticket number are equivalent to returning directly to the second kill failure when the queue is full.
Solution
From the above scenario, we can easily think of a solution that is server-side notification, so how to achieve server-side asynchronous notification? Next, the protagonist begins to debut, which is our Websocket.
WebSocket is a network technology that HTML5 began to provide for full-duplex communication between browsers and servers. Depending on this technology, we can realize the long connection between the client and the server, and the two-way real-time communication.
HTTP VS WebSocket
Features:
Asynchronous, event triggered
Can send streaming files such as text, pictures, etc.
The data format is lightweight, the performance overhead is low, and the communication is efficient.
Client-side socket using ws or wss protocol can achieve real push function.
Disadvantages:
Some browsers do not support it, the degree and manner of browser support are different, and all kinds of compatible writing methods are needed.
Integration case
Because SpringBoot is used in our second-kill architecture project case, integrating webSocket is also relatively simple.
First, pom.xml introduces the following dependencies:
Org.springframework.boot spring-boot-starter-websocket
WebSocketConfig configuration:
/ * * WebSocket configuration * Creator's Java Notes * creation time May 29th 2018 * / @ Configuration public class WebSocketConfig {@ Bean public ServerEndpointExporter serverEndpointExporter () {return new ServerEndpointExporter ();}}
WebSocketServer configuration:
@ ServerEndpoint ("/ websocket/ {userId}") @ Componentpublic class WebSocketServer {private final static Logger log = LoggerFactory.getLogger (WebSocketServer.class); / / static variable to record the current number of online connections. It should be designed to be thread safe. Private static int onlineCount = 0; / the thread-safe Set of the concurrent package, which is used to store the corresponding MyWebSocket object for each client. Private static CopyOnWriteArraySet webSocketSet = new CopyOnWriteArraySet (); / / A connection session with a client through which you need to send data to the client private Session session; / / receive userId private String userId= "; / * the method called successfully for connection establishment * / @ OnOpen public void onOpen (Session session,@PathParam (" userId ") String userId) {this.session = session; webSocketSet.add (this) / / add addOnlineCount () to set; / / add 1 log.info to the number of online users ("start listening in a new window:" + userId+ "); this.userId=userId; try {sendMessage (" connected successfully ");} catch (IOException e) {log.error (" websocket IO exception ") }} / * * connection closes the method called * / @ OnClose public void onClose () {webSocketSet.remove (this); / / removes subOnlineCount () from set; / / the number of lines minus 1 log.info ("A connection is closed! The current number of people online is "+ getOnlineCount ();} / * the method called after receiving the client message * @ param message client sends the message * / @ OnMessage public void onMessage (String message, Session session) {log.info (" receive message from window "+ userId+": "+ message) / / for (WebSocketServer item: webSocketSet) {try {item.sendMessage (message);} catch (IOException e) {e.printStackTrace () } / * @ param session * @ param error * / OnError public void onError (Session session, Throwable error) {log.error ("error occurs"); error.printStackTrace () } / * implement active push by server * / public void sendMessage (String message) throws IOException {this.session.getBasicRemote () .sendText (message);} / * Group Custom message * * / public static void sendInfo (String message,@PathParam ("userId") String userId) {log.info ("push message to window" + userId+ ", push content:" + message) For (WebSocketServer item: webSocketSet) {try {/ / here you can set only push to this userId, if it is null, then push all if (userId==null) {item.sendMessage (message);} else if (item.userId.equals (userId)) {item.sendMessage (message) } catch (IOException e) {continue;} public static synchronized int getOnlineCount () {return onlineCount;} public static synchronized void addOnlineCount () {WebSocketServer.onlineCount++;} public static synchronized void subOnlineCount () {WebSocketServer.onlineCount--;}}
KafkaConsumer consumption configuration, which notifies the user whether the second kill is successful:
/ * * Consumer spring-kafka 2.0 + relies on JDK8 * @ author By https://blog.52itstyle.com * / @ Componentpublic class KafkaConsumer {@ Autowired private ISeckillService seckillService; private static RedisUtil redisUtil = new RedisUtil () / * listens to the seckill topic, reads * @ param message * / @ KafkaListener (topics = {"seckill"}) public void receiveMessage (String message) {/ / receives the message from the channel and performs the second kill operation String [] array = message.split (";") If (redisUtil.getValue (array [0])! = null) {/ / control layer has been judged. In fact, there is no need to judge Result result = seckillService.startSeckil (Long.parseLong (array [0]), Long.parseLong (array [1]); if (result.equals (Result.ok () {WebSocketServer.sendInfo (array [0] .toString (), "second kill success") / / push to the front desk} else {WebSocketServer.sendInfo (array [0] .toString (), "second kill failed"); / / push to the front desk redisUtil.cacheValue (array [0], "ok"); / / second kill ends}} else {WebSocketServer.sendInfo (array [0] .toString (), "second kill failed") / / push to the front desk}
WebSocket.js Front desk Notification Logic:
$(function () {socket.init ();}); var basePath = "ws://localhost:8080/seckill/"; socket = {webSocket: ", init: function () {/ / userId: append if ('WebSocket' in window) {webSocket = new WebSocket (basePath+'websocket/1') } else if ('MozWebSocket' in window) {webSocket = new MozWebSocket (basePath+ "websocket/1");} else {webSocket = new SockJS (basePath+ "sockjs/websocket");} webSocket.onerror = function (event) {alert ("websockt connection error, please refresh the page and try again!")} WebSocket.onopen = function (event) {}; webSocket.onmessage = function (event) {var message = event.data; alert (message) / / determine whether the second kill is successful, self-processing logic};}} client API client communicates with server
Send () sends data to the remote server
Close () closes the websocket link
Listening function
Onopen triggers this event when a network connection is established
Onerror triggers this event when an error occurs on the network
Onclose triggers this event when websocket is closed
The event triggered by onmessage when the websocket receives a message from the server is also the most important listening event in communication. Msg.data
ReadyState attribute
This property returns the state in which websocket is located.
CONNECTING (0) websocket is trying to establish a connection with the server
OPEN (1) websocket has established a connection with the server
CLOSING (2) websocket is closing the connection to the server
CLOSED (3) websocket has closed the connection to the server
Open source solution goeasy
GoEasy real-time Web push supports backend push and foreground push: background push can choose Java SDK and Restful API to support all development languages; foreground push: JS push. No matter which way you choose to push the code is very simple (10 minutes can be done). Because it supports both websocket and polling connections, it takes into account most mainstream browsers, and lower versions of IE browsers also support it.
Pushlets
Pushlets implements the "push" message through a long connection. The push mode is divided into Poll (polling) and Pull (pull).
Pushlet
Pushlet is an open source Comet framework, Pushlet uses the observer model: the client sends requests and subscribes to events of interest; the server assigns a session ID to each client as a tag, and the event source sends the new events to the subscriber's event queue by multicast.
In fact, as mentioned earlier, although WebSocket has many advantages, it is quite resource-consuming for servers to maintain many persistent connections, and server clusters and browser or client compatibility problems will also bring some uncertainties. A general understanding of the practices of major manufacturers, most of them are based on polling, such as: Tencent PC Wechat login, JD.com Mall payment success notification and so on.
Some friends may ask, won't polling be more resource-consuming? In fact, in my opinion, some polling is impossible to penetrate into the back-end database query service, such as the second kill, a cache token can determine whether the second kill is successful. Compared with the long connection of WS and its uncertain factors, polling is relatively appropriate in the second kill scenario.
The above is how to build a distributed second kill system for WebSocket push notification. If you happen to have similar doubts, please refer to the above analysis to understand. If you want to know more about it, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.