How to implement read and unread messages on DingTalk?

Preface

In an app, the message page includes various notification categories such as wallet notifications and recent visitors. Each category may have new notification messages to implement read and unread functions, including how many unreads are included. How is this implemented? For example, if user A visits user B's homepage, can he use rabbitmq to send a notification message to B? Can the cost be affordable when the volume is large? Are there any low-cost solutions?

img

small talk

It's a good question, but it's a pity that the other answers are either generalized and taken for granted, or they are just talking about others and don't have a serious answer.

This is a very common requirement. When meeting this type of requirement, the first thing to do is to design a suitable business model. Then this model is a " dialogue model ".

Treat the "Settings", "Earn Points", "Recent Listeners", "Friends and Newcomers", and "Recent Visitors" in the question as a "virtual person", and you and the "virtual person" form a "conversation list " ( msg_group)"

The difference between a " virtual person " and a normal person is that the conversation between the virtual person and you is one-way. He can only send you messages, but you cannot reply.

All, to determine whether there is a little red dot, or what the number of the little red dot is, is to simply get the number of unread messages in your conversation with the virtual person.

"Recent Visits" tab

When someone visits your homepage, the backend will send you a message as the "recently visited" virtual person, but there is also a special mark in the message to indicate the source. In addition to the total amount, we also need to pull the number of messages from different sources. Of course, an action does not necessarily only send one message. For example, there is a diamond key "message" at the bottom of the picture. It is the sum of all messages. Therefore, when delivering other messages, it must be delivered once, but it only displays An unread number, so this message only needs a msg_id and does not require a message payload.

How to display the front end

Depend on specific product requirements.

Each conversation can be regarded as a msg_group, which is a message queue (note, not the message queue we often call ). The msg_id of each msg increases in an orderly manner. As for msg_id, it is only ordered within the queue or globally. , it depends on your choice. Generally, there is no need to optimize the data within 1 billion, as long as the number issuer is in order globally. This queue has basic information: participants (the example in the picture only has 2, you and the "virtual person"), maximum_msg_id.

You only need to save a last_pull_msg_id or last_read_msg_id, and bring this last_msg_id when pulling information.

Of course, the storage and reading of message lists are more diverse. It can be MySQL, nosql, hbase , redis. Generally we use mixed storage, especially old data is stored in hbase, older data is stored in mysq or nosql, and new data is stored in redis. Cloud vendors also have storage products specifically designed for such scenarios. In most cases, we only need one quantity, which is always taken from maximal_id forward. If it is not finished after fetching 100 items, it will directly return 99+ and it is finished.

In fact, the requirements in the figure, such as "settings" and "privacy settings", are global to the entire product, so you can create a simple " broadcast message mode ". The broadcast mode is to maintain a one-way message queue. All Anyone can pull messages from this queue, they only need to maintain their own last_id.

" Read and Unread ". It contains two meanings, one is to judge whether you have read the content, and the other is to count , that is, how many people have read the content.

Long tail reasons

If you use Redis storage, the cost is very high and the waste is very serious. If redis is not used, once historical data is flushed, it will be very, very slow. Bitmap is definitely not possible here , because bitmao needs to load all the data, which is obviously not feasible.

At this time, the usual strategies are "[log record]" and "comb". Every time we generate an action, such as reading, liking, and collecting, a log record will be generated (cancellation, cancellation of like... is also an independent log record) , we collect these records in a unified manner through a specialized big data system, and then count the data in multiple dimensions and store the statistical results. When the front-end obtains the data, it first retrieves it from the cache. If it cannot be retrieved, it then retrieves it through comb. The data size of comb is much smaller than log record, and the query speed is very fast.

Because log records do not involve queries, there is no need to use a database . They are generally stored directly in cheap storage media such as hbase or cassandra .

Popular content

User interaction is very active, so when writing log record, the cache will be updated directly and synchronously. However, the cached data is not guaranteed to be very accurate. It just confuses the user. The accurate data is based on the log record. You are in wb You can often see that the number of likes on popular content does not match the actual number. Because of wb 's cache and independent counter, the actual data is not synchronized.

This article is published by OpenWrite, a blog that publishes multiple articles !

Guess you like

Origin blog.csdn.net/qq_33589510/article/details/132595620