rabbitmq簡(jiǎn)介:
MQ全稱為Message Queue, 消息隊(duì)列(MQ)是一種應(yīng)用程序?qū)?yīng)用程序的通信方法。應(yīng)用程序通過讀寫出入隊(duì)列的消息(針對(duì)應(yīng)用程序的數(shù)據(jù))來(lái)通信,而無(wú)需專用連接來(lái)鏈接它們。消息傳遞指的是程序之間通過在消息中發(fā)送數(shù)據(jù)進(jìn)行通信,而不是通過直接調(diào)用彼此來(lái)通信,直接調(diào)用通常是用于諸如遠(yuǎn)程過程調(diào)用的技術(shù)。排隊(duì)指的是應(yīng)用程序通過 隊(duì)列來(lái)通信。隊(duì)列的使用除去了接收和發(fā)送應(yīng)用程序同時(shí)執(zhí)行的要求。其中較為成熟的MQ產(chǎn)品有IBM WEBSPHERE MQ。
本節(jié)的內(nèi)容是用戶注冊(cè)時(shí),將郵箱地址先存入rabbitmq隊(duì)列,之后返回給用戶注冊(cè)成功;之后消息隊(duì)列的接收者從隊(duì)列中獲取消息,發(fā)送郵件給用戶。
一、RabbitMQ介紹
如果之前對(duì)rabbitmq不了解,推薦先看一下RabbitMQ Quick(快速手冊(cè))。
1、rabbitmq在mac上的安裝。
2、rabbitmq簡(jiǎn)單介紹。
生產(chǎn)者: 負(fù)責(zé)發(fā)送消息到Exchange。
Exchange: 按照一定的策略,負(fù)責(zé)將消息存入到指定的隊(duì)列。
隊(duì)列queue: 負(fù)責(zé)保存消息。
消費(fèi)者: 負(fù)責(zé)從隊(duì)列中提取消息。
binding: 負(fù)責(zé)Exchange和隊(duì)列的關(guān)聯(lián)映射,Exchange和queue是多對(duì)多的關(guān)系。
二、RabbitMQ在Spring中的實(shí)現(xiàn)
1、引入依賴包。
1
2
3
4
5
6
7
8
9
10
|
<dependency> <groupId>org.springframework.amqp</groupId> <artifactId>spring-amqp</artifactId> <version>1.6.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.amqp</groupId> <artifactId>spring-rabbit</artifactId> <version>1.6.0.RELEASE</version> </dependency> |
2、rabbitmq配置文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
<?xml version= "1.0" encoding= "UTF-8" ?> <beans:beans xmlns= "http://www.springframework.org/schema/rabbit" xmlns:beans= "http://www.springframework.org/schema/beans" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" > <!--1、配置連接工廠, 如果不配置host, port, username, passowrd, 則按默認(rèn)值localhost:5672, guest/guest--> <!--<connection-factory id= "connectionFactory" />--> <connection-factory id= "connectionFactory" host= "localhost" port= "5672" username= "everSeeker" password= "333" /> <!--2、配置隊(duì)列queue, Exchange, 以及將他們結(jié)合在一起的binding--> <!--在queue以及exchange中, 有一個(gè)重要的屬性durable, 默認(rèn)為 true , 可以防止宕機(jī)后數(shù)據(jù)丟失。--> <!--在listener-container中, 有acknowledge屬性, 默認(rèn)為auto, 即消費(fèi)者成功處理消息后必須有個(gè)應(yīng)答, 如果消費(fèi)者程序發(fā)生異?;蛘咤礄C(jī), 消息會(huì)被重新放回隊(duì)列--> <admin connection-factory= "connectionFactory" /> <queue id= "userAlertEmailQueue" name= "user.alerts.email" durable= "true" /> <queue id= "userAlertCellphoneQueue" name= "user.alerts.cellphone" /> <!--durable默認(rèn)為 true --> <!--標(biāo)準(zhǔn)的AMQP Exchange有4種: Direct, Topic, Headers, Fanout, 根據(jù)實(shí)際需要選擇。--> <!--Direct: 如果消息的routing key與bingding的routing key直接匹配的話, 消息將會(huì)路由到該隊(duì)列上。--> <!--Topic: 如果消息的routing key與bingding的routing key符合通配符匹配的話, 消息將會(huì)路由到該隊(duì)列上。--> <!--Headers: 如果消息參數(shù)表中的頭信息和值都與binding參數(shù)表中相匹配, 消息將會(huì)路由到該隊(duì)列上。--> <!--Fanout: 不管消息的routing key和參數(shù)表的頭信息/值是什么, 消息將會(huì)路由到該隊(duì)列上。--> <direct-exchange name= "user.alert.email.exchange" durable= "true" > <bindings> <binding queue= "user.alerts.email" /> <!--默認(rèn)的routing key與隊(duì)列的名稱相同--> </bindings> </direct-exchange> <direct-exchange name= "user.alert.cellphone.exchange" > <bindings> <binding queue= "user.alerts.cellphone" /> </bindings> </direct-exchange> <!--3、配置RabbitTemplate發(fā)送消息--> <template id= "rabbitTemplate" connection-factory= "connectionFactory" /> <!--4、配置監(jiān)聽器容器和監(jiān)聽器來(lái)接收消息--> <beans:bean id= "userListener" class= "com.everSeeker.alerts.UserAlertHandler" /> <listener-container connection-factory= "connectionFactory" acknowledge= "auto" > <listener ref= "userListener" method= "handleUserAlertToEmail" queues= "userAlertEmailQueue" /> <listener ref= "userListener" method= "handleUserAlertToCellphone" queues= "userAlertCellphoneQueue" /> </listener-container> </beans:beans> |
如果配置connection-factory時(shí),采用默認(rèn)的guest/guest賬號(hào)密碼時(shí),有可能會(huì)出現(xiàn)org.springframework.amqp.AmqpAuthenticationException: com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.的錯(cuò)誤提示,解決辦法是新建一個(gè)管理員權(quán)限的用戶,并允許訪問虛擬主機(jī)。
步驟如下:
1、打開http://localhost:15672/
2、Admin ——> Users, 新建用戶,administrator權(quán)限。
3、Virtual Hosts,設(shè)置新建用戶允許訪問。
3、生產(chǎn)者發(fā)送消息到exchange。
1
2
3
4
5
6
7
8
9
10
11
12
|
@Service ( "userAlertService" ) public class UserAlertServiceImpl implements UserAlertService { private RabbitTemplate rabbit; @Autowired public UserAlertServiceImpl(RabbitTemplate rabbit) { this .rabbit = rabbit; } public void sendUserAlertToEmail(User user) { //convertAndSend(String exchange, String routingKey, Object object), 將對(duì)象object封裝成Message對(duì)象后, 發(fā)送給exchange rabbit.convertAndSend( "user.alert.email.exchange" , "user.alerts.email" , user); } } |
4、配置消費(fèi)者來(lái)接收消息。
1
2
3
4
|
public class UserAlertHandler { public void handleUserAlertToEmail(User user) { System.out.println(user); } |
三、通過javax.mail來(lái)發(fā)送郵件
1、引入依賴包。
1
2
3
4
5
|
<dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version> 1.4 . 7 </version> </dependency> |
2、配置郵件服務(wù)器信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
@Bean public MailSender mailSender(Environment env) { JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); //如果為普通郵箱, 非ssl認(rèn)證等, 比如163郵箱 mailSender.setHost(env.getProperty( "mailserver.host" )); mailSender.setPort(Integer.parseInt(env.getProperty( "mailserver.port" ))); mailSender.setUsername(env.getProperty( "mailserver.username" )); mailSender.setPassword(env.getProperty( "mailserver.password" )); mailSender.setDefaultEncoding( "utf-8" ); //如果郵件服務(wù)器采用了ssl認(rèn)證, 增加以下配置, 比如gmail郵箱, qq郵箱 Properties props = new Properties(); props.put( "mail.smtp.auth" , "true" ); props.put( "mail.smtp.starttls.enable" , "true" ); props.put( "mail.smtp.socketFactory.class" , "javax.net.ssl.SSLSocketFactory" ); props.put( "mail.smtp.socketFactory.port" , "465" ); mailSender.setJavaMailProperties(props); return mailSender; } |
3、發(fā)送郵件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@Component ( "userMailService" ) public class UserMailServiceImpl implements UserMailService { private MailSender mailSender; @Autowired public UserMailServiceImpl(MailSender mailSender) { this .mailSender = mailSender; } public void sendSimpleUserMail(String to, User user) { SimpleMailMessage message = new SimpleMailMessage(); message.setFrom( "xxxxxxxx@qq.com" ); message.setTo(to); message.setSubject(user.getUsername() + "信息確認(rèn)" ); message.setText(user.toString()); mailSender.send(message); } } |
4、消費(fèi)者調(diào)用發(fā)送郵件方法即可。
1、參考文獻(xiàn):Spring實(shí)戰(zhàn)(第4版)。
2、完整代碼在github,地址:https://github.com/everseeker0307/register。
以上所述是小編給大家介紹的Spring學(xué)習(xí)筆記3之消息隊(duì)列(rabbitmq)發(fā)送郵件功能,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)服務(wù)器之家網(wǎng)站的支持!
原文鏈接:http://www.cnblogs.com/everSeeker/p/5690984.html