preface

Only a bald head can be strong.

Welcome to our GitHub repository Star: github.com/ZhongFuChen…

I have an online mailing problem. Record it.

First, the background

One day, Xiao Wang told me, “Please check the online mail delivery, I found that the delivery failed.”

I went to DB to check the recent mail delivery situation and said, “It looks quite normal, there is no abnormal situation online. Maybe the mail is piled up in Redis and not consumed yet.”

select * from email order by id desc limit 100
Copy the code

First, let’s talk about the general implementation of my email:

What’s the good of that? Think of Redis as a message queue and dump all requests on Redis, which cuts the peak. The thread of machine A/B/C pulls messages to Redis at regular intervals and calls the mail interface to send them.

I will provide a function on the page for the business side to check whether various messages have been sent successfully. Since sending emails is an asynchronous operation, and my former colleague pursues real time when writing.

  • The current logic is: if push to Redis is successful and there is no message in Redis (indicating that machine A/B/C can process this email in time), then the email is considered to be sent successfully.

PS :(if the system does not have problems, actually this implementation is OK. Because the amount of mail sent is generally not very large (Redis does not stack messages), and the success rate of mail sent is quite high.

Back to the question, due to the above background, I guess: is it possible that this email was still piled up on Redis when Xiao Wang was checking the result, so he directly returned failure? Sure enough, I checked Redis, and there were 200 unanswered emails.

So I asked Xiao Wang: “How many emails have you sent?” “500 seals in 20 minutes is less than 1QPS,” Wang said. I thought for a moment: “That we have four machines, according to the truth is not so much.”

So I went to the online server to check the consumption log and found that only one machine was consuming the data of Redis. Went to check the error log is there a lot of error information, but did not find the error log…

So I checked the machine’s surveillance, and I didn’t see anything different. Which begs the question: why is there only one machine consuming Redis messages? The logs and monitoring information on the other three machines are clean.

Second, the solution

I couldn’t tell from the logs or the machine information that there was a problem, and then I remembered a command in Java: jstack

The jstack command is mainly used to view the call stack of Java threads and can be used to analyze thread problems (such as deadlocks).

Jstack detailed usage and tutorial: www.cnblogs.com/kongzhongqi…

So I ran the jstack command and searched the message for “Email”. I found it:

That’s easy, just search for keywords like “Java sending mailbox thread blocking” and you should have a solution.

In the end, it was discovered that some threads blocked while sending the mail because the timeout was not configured.

  • Mail. The SMTP. Connectiontimeout: connection time limit, the unit milliseconds. It’s about how long it takes to establish a connection to the mail server. The default is unlimited.
  • Mail.smtp. timeout: indicates the time limit for receiving mails, in milliseconds. This is about how long it takes to receive an email. The default is unlimited.
  • Mail.smtp. writeTimeout: indicates the time limit for sending emails, in milliseconds. About the length of time the content was uploaded at the time the message was sent. The default is also unlimited.

The last

Happy to export dry Java technology public number: Java3y. The public account has more than 200 original technical articles, massive video resources, beautiful brain map, attention can be obtained!

Think my article is good, give it a thumbs up!