阿里巴巴 一定要会spring会砍单吗吗

阿里MQ普通+顺序+延时消息 整合Spring
阿里MQ普通+顺序+延时消息 整合Spring
由于公司项目需要,研究了下AliWareMQ。阿里mq的普通消息和延时消息还是挺简单的。不过在顺序消息的时候出现了一些瓶颈。后来查阅和依据demo整理了一版融合Spring的版本。
mq配置文件(Spring)
主要是顺序消息的配置,以及多实例的配置(需要在控制台配置p/c)
${OrderProducerId}
${AccessKey}
${SecretKey}
${ONSAddr}
${ORDER_TOPIC}
${ConsumerId}
${AccessKey}
${SecretKey}
${ONSAddr}
${ORDER_TOPIC}
顺序生产者
package com.rqbao.mq.
import com.aliyun.openservices.ons.api.ONSF
import com.aliyun.openservices.ons.api.order.OrderP
import java.util.P
* Created by ricky on .
public class MQOrderProducer {
Properties producerProperties = new Properties();
public MQOrderProducer(Properties producerProperties) {
this.producerProperties = producerP
producer = ONSFactory.createOrderProducer(producerProperties);
public OrderProducer getOrderProducer(){
new MQOrderProducer(producerProperties);
producer.start();
shutdown(){
producer.shutdown();
public Properties getProducerProperties() {
return producerP
public void setProducerProperties(Properties producerProperties) {
this.producerProperties = producerP
public OrderProducer getProducer() {
public void setProducer(OrderProducer producer) {
this.producer =
顺序消费者
package com.rqbao.mq.
import com.aliyun.openservices.ons.api.M
import com.aliyun.openservices.ons.api.ONSF
import com.aliyun.openservices.ons.api.order.ConsumeOrderC
import com.aliyun.openservices.ons.api.order.MessageOrderL
import com.aliyun.openservices.ons.api.order.OrderA
import com.aliyun.openservices.ons.api.order.OrderC
import java.util.P
* Created by ricky on .
public class MQOrderConsumer {
Properties consumerProperties = new Properties();
public MQOrderConsumer(Properties consumerProperties) {
this.consumerProperties = consumerP
consumer = ONSFactory.createOrderedConsumer(consumerProperties);
consumer.subscribe(consumerProperties.get(&ORDER_TOPIC&).toString(), consumerProperties.get(&TAG&).toString(),
new MessageOrderListener() {
public OrderAction consume(final Message message, final ConsumeOrderContext context) {
System.out.println(message);
return OrderAction.S
new MQOrderProducer(consumerProperties);
consumer.start();
shutdown(){
consumer.shutdown();
public Properties getConsumerProperties() {
return consumerP
public void setConsumerProperties(Properties consumerProperties) {
this.consumerProperties = consumerP
public OrderConsumer getConsumer() {
public void setConsumer(OrderConsumer consumer) {
this.consumer =
#ALiMQ相关参数
AccessKey=XXXXXX
SecretKey=XXXXXXX
#阿里云MQ线上地址
#PropertyKeyConst.ONSAddr 请根据不同Region进行配置
#公网测试: https://onsaddr-/rocketmq/nsaddr4client-internet
#公有云生产: https://onsaddr-:8080/rocketmq/nsaddr4client-internal
#杭州金融云: https://jbponsaddr-:8080/rocketmq/nsaddr4client-internal
#深圳金融云: https://mq4finance-sz.:8080/rocketmq/nsaddr4client-internal
ONSAddr=https://onsaddr-/rocketmq/nsaddr4client-internet
topic=RICKY_CGBUSINESS_LOCAL
ORDER_TOPIC=RICKY_CGBUSINESS_TEST
ProducerId=PID_RICKYCG_LOCAL
OrderProducerId=PID_RICKYCG_TEST
ConsumerId=CID_RICKYCG_LOCAL
OrderConsumerId=CID_RICKYCG_TEST
顺序消息生产
mport com.aliyun.openservices.ons.api.M
import com.aliyun.openservices.ons.api.SendR
import com.aliyun.openservices.ons.api.order.OrderP
import com.mon.config.G
import org.apache.log4j.L
import org.springframework.beans.factory.InitializingB
import org.springframework.beans.factory.annotation.A
import org.springframework.stereotype.S
import java.util.D
import java.util.UUID;
* Created by ricky on .
*MQ消息生产功能,可能附加一些其他功能
public class MQOrderService implements InitializingBean{
private static final Logger logger = Logger.getLogger(MQOrderService.class);
@Autowired
MQOrderProducer mqOrderP
* 发送顺序MQ消息
* @param TAG 业务tag
tag将使用CGUTILS中的存管接口变量
* @param msg 需传递对应接口需要参数,格式待考究
delayTime 延迟时间
3000---&3s
public String sendOrderMQMsg(String TAG,String msg){
OrderProducer producer=mqOrderProducer.getOrderProducer();
Message message = new Message(Global.getConfig(&ORDER_TOPIC&), TAG,msg.getBytes());
// 设置代表消息的业务关键属性,请尽可能全局唯一。
String orderId = &rqb_& + UUID.randomUUID().toString().replaceAll(&-&,&&);
message.setKey(orderId);
// 分区顺序消息中区分不同分区的关键字段,sharding key于普通消息的key是完全不同的概念。
// 全局顺序消息,该字段可以设置为任意非空字符串。
String shardingKey = String.valueOf(orderId);
SendResult sendResult = producer.send(message, shardingKey);
if (sendResult != null) {
System.out.println(new Date() + & Send mq message success! Topic is:& + Global.getConfig(&topic&) + &msgId is: & + sendResult.getMessageId());
return sendResult.toString();
public void afterPropertiesSet() throws Exception {
顺序消息消费
具体在MQOrderConsumer中写消费处理
MQ存在重复消费的问题,我这里的解决方案是进行MQ消息记录,比如消息有tag再加上body中相关的业务id,联合组成唯一索引,避免重复消费问题。这周阿里三面的一个面试题目:在Spring MVC 中,控制器controller 怎么样找到对应的业务模型来出来以后的请求 - ITeye问答
我们知道用户请求URL可以注解的方式来把UR与控制器controller映射起来,但怎么样把控制器controller 与业务模型映射起来是url通过controller找到对应的业务模型?也即是说控制器与业务模型怎么样建立关系?
问题补充:这周阿里三面的一个面试题目:在Spring MVC 中,控制器controller 怎么样找到对应的业务模型来处理用户的请求
看你对问题的描述就知道你对问题理解的不够深刻
源码里面有一个handerAdapter负责绑定Controller与具体的方法之间的映射。
道理很简单,但要说的很明白,还是需要熟悉源码才可以。
这问题,也拿来提问。
ModelAndView ,通过url绑定的方法method,其实跟struts2的差不多了 ,就是springMVC更轻量级,好用些。
系统加载的时候解析注解,原理应该如下吧(肯定不会这么简单):
Map&String,Method& mapping = new HashMap();
mapping.put("/user/login",loginMethod);
mapping.put("/user/register",registerMethod);
竟然还成了热点问题。。。
如果是这个意思:比如url和controller具有匹配关系,那怎么通过url找到相应的service? 当然这个只考虑比如简单的crud的话; 可以这样:
1、url设计的问题: /{module}/others 比如:/user/create ,其中others是service的method名字,方便反射掉
2、controller的写法:
@Controller
@RequestMapping(“/user”)
public class UserController {
&&&
3、自动搜索相关的service:
3.1、根据controller名字得到相关的service名字,如UserService(有规则可循的);
3.2、根据请求的url找,@RequestMapping(“/user”) 到UserService 也是能找到规律的
4、找到service之后,再根据method名字 自动调用service方法;
不过这些只适合基本的crud, 如果复杂场景,还是要写代码的。
不过问题描述的确实不大清楚。
的确描述不太清楚,是说handleMapping的部分还是viewReslover部分呢?
楼主应该说的是mvc如何实现将request中的请求数据绑定到对应的Model中,这个是通过spring mvc 的dataBinder机制以及HttpMessageConverter实现的,具体可以去看下对应的源码实现
阿里会问这种问题?
ViewResolver 提供的控制功能,很典型的内置路由器:
org.springframework.web.servlet.view.ContentNegotiatingViewResolver
也可以自己扩展,主要作用是截获请求的头信息比如url contant-type之类的转发到不同的controller模块,有时间看看源码把,其实看看就懂了。
你是说把& 参数自动绑定到 pojo属性 这个吧!
简单的反射就可以啊!
没搞明白你的意思。
楼主这你都没说明白。。
@Resource
UserS
url匹配啊,没搞明白你说的意思
已解决问题
未解决问题上一篇我们使用到的ApplicationListener是无序的,结合异步调度它能满足了我们的大部分应用场景,但现在我们来个另类的需求,我们来模拟一条作业调度流水线,它不能异步,必须按照先后次序执行不同的任务才能得到我们的最终结果。
需求示例:现在假如华中科技大学的小白想
上一篇我们使用到的ApplicationListener是无序的,结合异步调度它能满足了我们的大部分应用场景,但现在我们来个另类的需求,我们来模拟一条作业调度流水线,它不能异步,必须按照先后次序执行不同的任务才能得到我们的最终结果。
需求示例:现在假如华中科技大学的小白想要为它的智能机器人作品申报国家创新奖,需要经过学校、省级创新科研机构、国家创新科研机构逐层审核。我们尝试通过事件来实现,核心就在监听器实现SmartApplicationListener接口。示例如下:
1. 配置事件发布者小白:
public class XiaoBai implements ApplicationContextAware {
private ApplicationContext applicationC
public void reportWorks(){
AuditEvent auditEvent = new AuditEvent(this);
applicationContext.publishEvent(auditEvent);
System.out.println("最终审核结果:" + auditEvent.getStatus() + "——" + auditEvent.getAdvice());
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationC
关于上述配置可参考我的上一篇文章
2. 配置审核事件源
public class AuditEvent extends ApplicationEvent {
public AuditEvent(Object
super(source);
status = true;
advice = "尚未审核";
3. 配置事件监听器
我们实现需求的核心部分来了,先上代码
/******************学校审核监听器******************/
public class SchoolListener implements
SmartApplicationListener
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("获取当前的申报状态为:"+((AuditEvent)event).getStatus() + "——" + ((AuditEvent)event).getAdvice());
((AuditEvent)event).setStatus(true);
((AuditEvent)event).setAdvice("学校审核意见:有创意,非常棒!");
public int getOrder() {
public boolean supportsEventType(Class&? extends ApplicationEvent& eventType) {
return eventType == AuditEvent.
public boolean supportsSourceType(Class&?& sourceType) {
return sourceType == XiaoBai.
/******************省级审核监听器******************/
public class ProvinceListener implements
SmartApplicationListener
public void onApplicationEvent(ApplicationEvent event) {
if(((AuditEvent)event).getStatus()){
System.out.println("获取当前的申报状态为:"+((AuditEvent)event).getStatus() + "——" + ((AuditEvent)event).getAdvice());
((AuditEvent)event).setStatus(true);
((AuditEvent)event).setAdvice("省级审核意见:还行,通过吧!");
public int getOrder() {
public boolean supportsEventType(Class&? extends ApplicationEvent& eventType) {
return eventType == AuditEvent.
public boolean supportsSourceType(Class&?& sourceType) {
return sourceType == XiaoBai.
/******************国家级审核监听器******************/
public class CountryListener implements
SmartApplicationListener
public void onApplicationEvent(ApplicationEvent event) {
if(((AuditEvent)event).getStatus()){
System.out.println("获取当前的申报状态为:"+((AuditEvent)event).getStatus() + "——" + ((AuditEvent)event).getAdvice());
((AuditEvent)event).setStatus(true);
((AuditEvent)event).setAdvice("国家审核意见:一般般,勉强通过吧!");
public int getOrder() {
public boolean supportsEventType(Class&? extends ApplicationEvent& eventType) {
return eventType == AuditEvent.
public boolean supportsSourceType(Class&?& sourceType) {
return sourceType == XiaoBai.
在这里,我们的实例为了方便演示而简化配置。我们的发布源支持类型是小白,根据更实际的需求,我们可以让小白继承Student类,然后让sourceType只要是Student的子类即可,这样就能满足任何继承了Student的学生都能申报了。
在实现了SmartApplicationListener的监听器中,我们通过重写GetOrder方法来修改不同监听器的顺序,优先级越小,则越先被调用。通过配置不同的优先级,且让监听器之间阻塞调用。我们就能实现流水线式的有序事件调用,这在实际应用场景中还是蛮有意义的
5. 在IOC容器中注册监听器
id="schoolListener" class="test.event2.SchoolListener" /&
id="provinceListener" class="test.event2.ProvinceListener" /&
id="countryListener" class="test.event2.CountryListener" /&
id="xiaoBai" class="test.event2.XiaoBai" /&
6. 测试方法
public class MainTest {
public static void main(String args[]) throws InterruptedException{
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:test/event2/event.xml");
XiaoBai xiaobai = (XiaoBai) ac.getBean("xiaoBai");
xiaobai.reportWorks();
调用测试代码,我们得到运行结果:
获取当前的申报状态为:true——尚未审核
获取当前的申报状态为:true——学校审核意见:有创意,非常棒!
获取当前的申报状态为:true——省级审核意见:还行,通过吧!
最终审核结果:true——国家审核意见:一般般,勉强通过吧!
于是,小白的作品终于评上了国家创新科技奖了,这让他高兴了好一阵子。
本实例源码可到我的github仓库下的event2文件夹下载
版权声明:本文内容由互联网用户自发贡献,本社区不拥有所有权,也不承担相关法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至: 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
用云栖社区APP,舒服~
【云栖快讯】浅析混合云和跨地域网络构建实践,分享高性能负载均衡设计,9月21日阿里云专家和你说说网络那些事儿,足不出户看直播,赶紧预约吧!&&
基于全网公开发布数据、传播路径和受众群体画像,利用语义分析、情感算法和机器学习,分析公众对品牌形象、热点事件和公...
以阿里云成熟的商业化云服务为基础,为游戏开发者、运营企业提供专属集群、尊享VIP服务、专项扶持基金、及多场景多类...
阿里云机器学习是基于阿里云分布式计算引擎的一款机器学习算法平台。用户通过拖拉拽的方式可视化的操作组件来进行试验,...
为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效率,降低 IT 成本...
MaxCompute75折抢购
Loading...

我要回帖

更多关于 springmvc线程安全吗 的文章

 

随机推荐