精华内容
下载资源
问答
  • Spring Jms异步消息推送

    千次阅读 2015-08-31 17:32:19
    最近公司项目业务要求用户下单之后发送邮件通知功能,...因此,我在这里使用了异步消息推送服务,使用的技术:activeMQ+spring+jms,利用spring自带jms功能,实现了异步消息推送,这样即使邮件发送失败也不会影响主程

    最近公司项目业务要求用户下单之后发送邮件通知功能,邮件发送功能我使用的是spring自带的mail功能见我的其他博客有讲解,但是邮件这段加入进去之后不能够影响原有的程序功能,比如:邮件发送失败导致系统报异常影响订单交易程序,因此,我在这里使用了异步消息推送服务,使用的技术:activeMQ+spring+jms,利用spring自带jms功能,实现了异步消息推送,这样即使邮件发送失败也不会影响主程序。好了,废话说多了,见代码。

    //配置文件

    <!-- started spring-jms config -->
    	<context:component-scan base-package="com.maimai.jms"/>
    	<!-- connection to amq -->
    	<amq:connectionFactory id="connectionFactory" 
    		brokerURL="tcp://localhost:61616"/>
    	<amq:queue id="queue" physicalName="spitter.queue"></amq:queue>
    	
    	<bean id="jsmTemplate" class="org.springframework.jms.core.JmsTemplate">
    		<property name="connectionFactory" ref="connectionFactory"></property>
    	</bean>
    	<jms:listener-container connection-factory="connectionFactory">
    		<jms:listener destination="spitter.queue" ref="jmsreciever" method="getStr"/>
    	</jms:listener-container>
    	<bean id="jmsreciever" class="com.maimai.jms.RecieverJMS" />
    	<!-- ended spring-jms config -->

    //发送消息定义

    package com.maimai.jms;
    
    import javax.jms.JMSException;
    import javax.jms.Message;
    import javax.jms.Session;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jms.core.JmsTemplate;
    import org.springframework.jms.core.MessageCreator;
    import org.springframework.stereotype.Component;
    
    @Component
    public class SenderJMS {
    	
    	@Autowired
    	JmsTemplate jmsTemplate;
    	
    	public void send(final String str){
    		
    		
    		this.jmsTemplate.send("spitter.queue", new MessageCreator() {
    			
    			public Message createMessage(Session session) throws JMSException {
    				// TODO Auto-generated method stub
    				
    				
    				return session.createTextMessage(str);
    			}
    		});
    	}
    	
    	
    }
    

    //接收消息定义

    package com.maimai.jms;
    
    import javax.jms.JMSException;
    import javax.jms.TextMessage;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jms.core.JmsTemplate;
    import org.springframework.stereotype.Component;
    
    @Component
    public class RecieverJMS {
    	
    	@Autowired
    	JmsTemplate jmsTemplate;
    	
    	public void getStr(String str) throws JMSException{
    	//	TextMessage tm = (TextMessage) jmsTemplate.receive();
    		
    	//	String str = tm.getText();
    		
    		System.out.println("==================================str="+str);
    	}
    }
    

    //程序调用jms,关键代码

    public String Login() throws NoSuchAlgorithmException, UnsupportedEncodingException{
    		this.jms.send("hello world !");
    		String result = Constant.JSON_EMPTY;}

    //打印结果

    2015-08-31 17:31:06,138 [http-8080-4] DEBUG [org.springframework.jms.core.JmsTemplate] - Sending created message: ActiveMQTextMessage {commandId = 0, responseRequired = false, messageId = null, originalDestination = null, originalTransactionId = null, producerId = null, destination = null, transactionId = null, expiration = 0, timestamp = 0, arrival = 0, brokerInTime = 0, brokerOutTime = 0, correlationId = null, replyTo = null, persistent = false, type = null, priority = 0, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = null, marshalledProperties = null, dataStructure = null, redeliveryCounter = 0, size = 0, properties = null, readOnlyProperties = false, readOnlyBody = false, droppable = false, text = hello world !}
     2015-08-31 17:31:06,145 [org.springframework.jms.listener.DefaultMessageListenerContainer#0-1] DEBUG [org.springframework.jms.listener.DefaultMessageListenerContainer] - Received message of type [class org.apache.activemq.command.ActiveMQTextMessage] from consumer [ActiveMQMessageConsumer { value=ID:wwsoft-PC-63011-1441013456482-0:1:1:1, started=true }] of session [ActiveMQSession {id=ID:wwsoft-PC-63011-1441013456482-0:1:1,started=true}]
     ==================================str=hello world !
    2015-08-31 17:31:06,174 [http-8080-4] DEBUG [org.mybatis.spring.SqlSessionUtils] - Creating a new SqlSession




    展开全文
  • MVC异步消息推送机制

    2014-01-26 13:51:00
    在MVC里面,有异步控制器,可以实现模拟消息推送机制功能 1.控制器要继承至AsyncController,如 public class RealTimeController : AsyncController { } 2.action要采集异步形式,且成对出现Async和Completed...

    在MVC里面,有异步控制器,可以实现模拟消息推送机制功能

    1.控制器要继承至AsyncController,如

    public class RealTimeController : AsyncController

    {

    }

    2.action要采集异步形式,且成对出现Async和Completed,如

     public void IndexAsync(string url)

    {

    }

     public void IndexCompleted(Info u)

    {

    }

    3.在Async中,要说明异步等待操作

       AsyncManager.OutstandingOperations.Increment();

    4.在有数据时候,调用

    AsyncManager.Parameters["Info"] = u;//这是返回给Completed中调用

    AsyncManager.OutstandingOperations.Decrement(); //类似执行回调Completed

    5,最好执行Completed,返回给客户端

      

        

    转载于:https://www.cnblogs.com/gzalrj/p/3533970.html

    展开全文
  • SpringBoot集成DingTalk钉钉机器人实现消息同步/异步预警推送

    V2.0版本新增支持以下功能

    • 新增Dinger层对消息对象配置指定钉钉机器人
    • 新增Dinger层统一管理消息对象,仅支持text和markdown格式
      • 支持xml方式配置
      • 支持注解方式配置
    • 新增关闭指定消息体和XXXDinger内定义的所有消息体

    SpringBoot集成DingTalk钉钉机器人实现消息同步/异步预警推送 2.0版本

     

    开发环境说明

    • JDK1.8
    • springboot版本: 2.0.3.RELEASE

     

    快速入门

    V1.0快速使用文档

     


    1.X版本使用文档


    引入maven依赖

    <dependency>
        <groupId>com.github.answerail</groupId>
        <artifactId>dingtalk-spring-boot-starter</artifactId>
        <version>1.0.5-RELEASE</version>
    </dependency>
    
    <!-- okhttp3依赖 -->
    <dependency>
        <groupId>com.squareup.okhttp3</groupId>
        <artifactId>okhttp</artifactId>
        <version>3.10.0</version>
    </dependency>
    

     

    YAML配置

    spring:
      dingtalk:
      	# 必填, 项目ID, 推荐值: ${spring.application.name}
        project-id: ${spring.application.name}
        # 必填
        token-id: c60d4824e0ba4a30544e81212256789331d68b0085ed1a5b2279715741355fbc
        # 选填, 自定义关键字
        title: 消息推送
    

    token-id获取方式: token-id的值就是机器人的Webhook地址中access_token的值。

     

    SpringBoot中使用

    text消息类型

    public class Demo {
            @Autowired
            private DingTalkRobot dingTalkRobot;
            
            public void test() {
                String keyword = "DYZ3AALTRBD2AIDLL0Y3EQ4TYGLJDUM";
                String subTitle = "服务启动通知";
                String content = "服务启动异常啦。。。";
    
                // 方式1-text类型
                dingTalkRobot.send(MsgTypeEnum.TEXT, keyword, subTitle, content);
    
                // 方式2-text类型带@指定群成员
                dingTalkRobot.send(MsgTypeEnum.TEXT, keyword, subTitle, content,
                        Lists.newArrayList("135XXXXXXXX"));
    
                // 方式3-text类型带@全部群成员
                dingTalkRobot.sendAll(MsgTypeEnum.TEXT, keyword, subTitle, content);
            }      
        }
    

     

    markdown消息类型

        public class Demo {
            @Autowired
            private DingTalkRobot dingTalkRobot;
            
            public void test() {
                String keyword = "DYZ3AALTRBD2AIDLL0Y3EQ4TYGLJDUM";
                String subTitle = "服务启动通知";
                String content = "服务启动异常啦。。。";
    
                // 方式1-markdown类型
                dingTalkRobot.send(MsgTypeEnum.MARKDOWN, keyword, subTitle, content);
    
                // 方式2-markdown类型带@指定群成员
                dingTalkRobot.send(MsgTypeEnum.MARKDOWN, keyword, subTitle, content,
                        Lists.newArrayList("135XXXXXXXX"));
            }      
        }
    

    markdown消息体暂时不支持@全部

     


    以下为个性化配置部分


    定制化配置

    如果只是简单的往钉钉群推动消息的, 以上内容可以满足你的需求。如果有需要考虑定制化配置的, 可继续往下阅读, 以下内容为独立配置文档说明, 如需进行整体配置请参考个性化整体配置

    自定义消息体

        @Configuration
        public class MyConfiguration {
            // 自定义text类型消息体
            @Bean
            public CustomMessage textMessage() {
                return (dingTalkProperties, subTitle, keyword, content, phones) -> {
                    String message = null;
                    // ...
                    return message;
                };
            }
        
            // 自定义markdown类型消息体
            @Bean
            public CustomMessage markDownMessage() {
                return (dingTalkProperties, subTitle, keyword, content, phones) -> {
                    String message = null;
                    // ...
                    return message;
                };
            }
        }
    

    在默认设置的消息体中可以根据keyword字段的值快速定位到系统日志信息

     

    默认text消息格式

    【通知】 服务启动通知
    - 项目名称: oms
    - 检索关键字: DYZ3AALTRBD2AIDLL0Y3EQ4TYGLJDUM
    - 内容: 服务启动异常啦。。。.
    

     

    默认markdown消息格式


    【通知】 服务启动通知
    • 项目名称: oms
    • 检索关键字: DYZ3AALTRBD2AIDLL0Y3EQ4TYGLJDUM
    • 内容: 服务启动异常啦。。。

     

    自定义异常回调

        @Configuration
        public class MyConfiguration {
            // 自定义异常回调函数
            @Bean
            public Notice notice() {
                return (dkExCallable) -> {
                    // ...
                };
            }
        }
    

    调用消息推送时出现异常时回调处理

     

    自定义签名体

    • 更改前: URL_PREV&sign=XXX&timestamp=XXX
    • 更改后: URL_PREV&timestamp=XXX&sign=XXX
        @Data
        @AllArgsConstructor
        public class SignDTO extends SignBase {
            private String sign;
            private Long timestamp;
        
            @Override
            public String transfer() {
                StringBuilder signStr = new StringBuilder(SEPERATOR);
                signStr
                        .append("timestamp=").append(this.timestamp).append(SEPERATOR)
                        .append("sign=").append(this.sign);
                return signStr.toString();
            }
        }
    
        @Configuration
        public class MyConfiguration {
            @Bean
            public DkSignAlgorithm<SignDTO> dkSignAlgorithm() {
                return new DkSignAlgorithm<SignDTO>() {
                    @Override
                    public SignDTO sign(String secret) throws Exception {
                        Long timestamp = System.currentTimeMillis();
                        // TODO 使用默认算法, 如果后期算法改变, 可在此更变签名算法
                        String sign = algorithm(timestamp, secret);
                        return new SignDTO(sign, timestamp);
                    }
                };
            }
        }
    

    该功能只针对后期版本变更进行扩展, 当前版本没有使用的必要

     

    自定义处理ID生成器

        @Configuration
        public class MyConfiguration {
            @Bean
            public DkIdGenerator dkIdGenerator() {
                return () -> {
                    String dkid = null;
                    // ...
                    return dkid;
                };
            }  
        }
    

    注意ID最好保证全局唯一, 同步调用直接返回响应结果,异步操作返回处理id(dkid)

     

    自定义异步执行结果回调处理器

        @Configuration
        public class MyConfiguration {
            @Bean
            public DkCallable dkCallable() {
                return (dkid, result) -> {
                    // ...
                };
            }    
        }
    

    此处方法形参(dkid, result),其中: dkid也就是异步通知的返回结果, result为请求实际的响应报文字符串。

    注意开启异步处理时使用内置线程池, 如果项目中有定义其他线程池配置, 注入线程池对象时请指定线程池名称。 如: @Qualifier("executor")

     

    自定义线程池(可选)

        @Configuration
        public class MyConfiguration {
            @Bean
    	    public Executor dingTalkExecutor() {
    	        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    	        // ...
    	        return executor;
    	    }
    	}
    

     

    自定义http客户端(可选)

        @Configuration
        public class MyConfiguration {
    	    @Bean
    	    public OkHttpClient okHttpClient() {
    	    	// ...
    	    }
    	}
    

     

    相关链接

    展开全文
  • SpringBoot集成DingTalk钉钉机器人实现消息同步/异步预警推送 2.0版本

    SpringBoot集成DingTalk钉钉机器人实现消息同步/异步预警推送1.0版本

     

    开发环境说明

    • JDK1.8
    • springboot版本: 2.0.3.RELEASE

     

    快速入门

    V2.0快速使用文档

     


    2.X版本使用文档


    jar包依赖

    <dependency>
        <groupId>com.github.answerail</groupId>
        <artifactId>dingtalk-spring-boot-starter</artifactId>
        <version>2.0.4-RELEASE</version>
    </dependency>
    
    <!-- 2.0.1及之前版本需引入 -->
    <!--
    <dependency>
        <groupId>com.squareup.okhttp3</groupId>
        <artifactId>okhttp</artifactId>
        <version>3.10.0</version>
    </dependency>
    -->
    

     

    配置文件

    spring:
      dingtalk:
        token-id: c60d4824e0ba4a30544e81212256789331d68b0085ed1a5b2279715741355fbc
        project-id: ${spring.application.name}
        title: 预警通知
        secret: APC3eb471b2761851d6ddd1abcndf2d97be21447d8818f1231c5ed61234as52d1w0
        # xml方式配置, 注解方式不需要配置
    	dinger-locations: classpath*:dinger/*.xml
    

    token-id获取方式: token-id的值就是机器人的Webhook地址中access_token的值。

     

    启动类设置

    @SpringBootApplication
    @MapperScan(basePackages = "com.jaemon.dt.mapper")
    // 标识Dinger层扫描路径
    @DingerScan(basePackages = "com.jaemon.dt.dinger")	
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class,args);
    
        }
    }
    
    • @DingerScan: 标识Dinger层扫描路径

     

    Dinger层

    注解方式

    public interface OrderDinger {
    
        @DingerText(value = "订单号${orderNum}下单成功啦, 下单金额${amt}", phones = {"13520200906"})
        DingTalkResult orderSuccess(
            @Parameter("orderNum") String orderNo, 
            @Parameter("amt") BigDecimal amt
        );
    
        @DingerMarkdown(
                value = "#### 下单失败啦 @13520200906\n - 订单号: ${orderNo}\n - 标识: ${flag}\n - 数量: ${num}",
                title = "下单结果反馈",
                phones = {"13520200906"},
                tokenId = @DingerTokenId(
                        value = "c60d4824e0ba4a30544e81212256789331d68b0085ed1a5b2279715741355fbc",
                        secret = "APC3eb471b2761851d6ddd1abcndf2d97be21447d8818f1231c5ed61234as52d1w0")
        )
        DingTalkResult orderFailed(String orderNo, int num, boolean flag);
    }
    
    • @Keyword: 标识关键词,用于根据关键词信息快速定位请求日志(主要用于发送钉钉消息异常时的日志定位);
    • @Parameter: 如果消息体中使用的参数变量和定义的入参名称不一致,可使用该注解进行个性化设置参数变量名称;
    • @DingerClose: 用于关闭 XXXDinger.java 或者指定其中的一个至多个方法;
      • 作用于Dinger类上,关闭Dinger类中所有方法通知;
      • 作用于方法上, 关闭当前方法通知;
    • @Dinger: 用于指定 @DingerScan 指定路径之外的 XXXDinger.java 文件

     

    xml方式

    配置文件新增dinger-locations路径配置

    spring:
      dingtalk:
    	dinger-locations: classpath*:dinger/*.xml
    

    如: resources/dinger/OrderDinger.xml

    OrderDinger.java接口层

    public interface OrderDinger {
        DingTalkResult orderSuccess(
            @Parameter("orderNum") String orderNo, 
            @Parameter("amt") BigDecimal amt
        );
    
        DingTalkResult orderFailed(String orderNo, int num, boolean flag);
    }
    

    OrderDinger.xml配置

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE dinger SYSTEM "dingtalk-dinger.dtd">
    <!DOCTYPE dinger PUBLIC "-//AnswerAIL//DTD Dinger 2.0//EN" "dingtalk-dinger.dtd">
    
    <dinger namespace="com.jaemon.dt.dinger.OrderDinger">
    
    	<message id="orderSuccess" type="TEXT">
    		<body>
    			<!-- <type>text</type> -->
    			<content>
    				订单号${orderNum}下单成功啦, 下单金额${amt}
    			</content>
    
    			<phones atAll="true" />
    		</body>
    
            <!-- 配置消息体使用的钉钉机器人信息 -->
    		<configuration async="false">
    			<token-id
    		secret="APC3eb471b2761851d6ddd1abcndf2d97be21447d8818f1231c5ed61234as52d1w0"
    		decrypt-key="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCeSpqEVuq2NVNDu2lJb">iH178Wn85rI+Mlguimxml79o5/w/CVGEjVWULfJog
    			</token-id>
                <!-- 是否异步发送 -->
    			<!-- <async-execute>true</async-execute> -->
    		</configuration>
    	</message>
    
    
    	<message id="orderFailed" type="MARKDOWN">
    		<body>
    			<!-- <type>markdown</type> --> 
    			<content title="下单结果反馈">
    				#### 下单失败啦 @13520200906
    				- 订单号: ${orderNo}
    				- 标识: ${flag}
    				- 数量: ${num}
    			</content>
    
    			<!-- markdown不支持@全部, 只支持@指定用户 -->
    			<phones>
    				<!-- 指定的phone的用户必须在tokenId群中 -->
    				<phone value="13520200906" />
    			</phones>
    		</body>
    	</message>
    </dinger>
    

    XXXDinger.xml 配置模板文档

     

    验证

    @Slf4j
    @RestController
    public class TestController {
        @Autowired
        private OrderDinger orderDinger;
    
        @GetMapping("/notify")
        public void notify() {
    		DingTalkResult result = orderDinger.orderSuccess("20200906", BigDecimal.valueOf(10000));
            log.info(JSON.toJSONString(result));
    
            result = orderDinger.orderFailed("20200906", 10, false);
            log.info(JSON.toJSONString(result));
        }
    }
    

     

    收到消息格式

    钉钉收到的orderSuccess通知消息


    • 订单号20200906下单成功啦, 下单金额1000@所有人

    钉钉收到的orderFailed通知消息


    下单失败啦 @XXX

    • 订单号: 20200906
    • 标识: false
    • 数量: 10

    展开全文
  • 郑昀 基于朱传志的设计文档 最后更新于2014/11/11 关键词: 异步消息 、订阅者集群、可伸缩、Push模式、Pull模式 本文档适用人员:研发 ...
  •  如子柳所说,电商系统『需要两种中间件系统,一种是实时调用的中间件(淘宝的HSF,高性能服务框架)、一种是异步消息通知的中间件(淘宝的Notify)』。那么用传统的 ActiveMQ/RabbitMQ 来实现 异步消息发布和订阅 ...
  • web创建消息推送保存至数据库后,后台从数据库获取数据并异步推送;即每次获取一条数据推送,推送成功后再获取第二条数据推送,依此类推,当没有数据时处于睡眠状态。我该怎么实现。
  • 优点:异步推送消息只要客户端发送异步请求就可以,不依赖客户端版本,不存在浏览器兼容问题。 一、 主要讲解技术点,异步实现服务器推送消息 二、 项目示例,聊天会话功能,主要逻辑如下:  由Logan向Charles...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 689
精华内容 275
关键字:

异步消息推送