96SEO 2026-02-19 10:31 0
Q概念用途特性安装RocketMQ掌握RocketMQ的api使用对producer、consumer进行详解了解RocketMQ的存储特点

简介及相关概念JavaAPISpringBoot整合RocketMQ消息的顺序收发消息系统的事务、存储、重试策略消息系统的集群
阿里中间件Notify用于交易核心信息的流转2010年B2B开始大规模使用ActiveMQ作为消息内核急需支持顺序消息、拥有海量消息堆积能力的消息中间件——MetaQ
年MetaQ发展到了3.0版本抽象除了通用的消息引擎RorcketMQ2015年RocketMQ进过双十一在可用性可靠性和稳定性等方面都有出色表现。
阿里消息中间件基于RocketMQ退出Aliware
MQ1.0开始为阿里云上的企业提供消息服务2016年RocketMQ进入Apache孵化
Group一类Producer的集合名称这类Producer通常发送同一类消息且发送逻辑一致
Group一类Consumer的集合名称这类Producer通常发送同一类消息且发送逻辑一致
RocketMQ的核心消息的发送、接收、高可用等需要定时发送自身情况到NameServer,默认10s发送一次超过2分钟会认为该broker失效
不同类型的消息以不同的Topic名称进行区分如User、Order等Message
下载地址https://archive.apache.org/dist/rocketmq/4.3.2/rocketmq-all-4.3.2-bin-release.zip
rocketmq-all-4.3.2-bin-release.zip
rocketmq-all-4.3.2-bin-release/#
os::commit_memory(0x00000005c0000000,
(errno12)启动错误因为RocketMQ的配置默认是生产环境的配置设置jvm的内存值比较大需要调整默认值
broker[iZ2zeg4pktzjhp9h7wt6doZ,
/opt/rocketmq-all-4.3.2-bin-release/bin
org.apache.rocketmq.example.quickstart.Producer接收消息测试
org.apache.rocketmq.example.quickstart.Consumerjava
dependenciesdependencygroupIdorg.apache.rocketmq/groupIdartifactIdrocketmq-client/artifactIdversion4.3.2/version/dependency
/dependenciesbuildpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdversion3.2/versionconfigurationsource1.8/sourcetarget1.8/targetencodingUTF-8/encoding/configuration/plugin/plugins
org.apache.rocketmq.client.exception.MQBrokerException;
org.apache.rocketmq.client.exception.MQClientException;
org.apache.rocketmq.client.producer.DefaultMQProducer;
org.apache.rocketmq.client.producer.SendResult;
org.apache.rocketmq.common.message.Message;
org.apache.rocketmq.remoting.common.RemotingHelper;
org.apache.rocketmq.remoting.exception.RemotingException;import
java.io.UnsupportedEncodingException;public
DefaultMQProducer(test-group);//specify
addressproducer.setNamesrvAddr(8.140.130.91:9876);//Lanuch
Message(TopicTest1,/*topic*/TAGA,/*tag*/(Hello
i).getBytes(RemotingHelper.DEFAULT_CHARSET)/*message
producer.send(msg);System.out.printf(%s%n,
broker的ip地址是172.17.0.1,为私有ip所以不可访问
/opt/rocketmq-all-4.3.2-bin-release/conf
broker.confbrokerIP18.140.130.91
brokerNamebroker_haoke_im#启动broker通过
/opt/rocketmq-all-4.3.2-bin-release/
/opt/rocketmq-all-4.3.2-bin-release/conf/broker.confAPI测试成功
foxiswho/rocketmq:broker-4.3.2#创建nameserver容器
/data/rmq-data/rmqserver/logs:/opt/logs
/data/rmq-data/rmqserver/store:/opt/store
foxiswho/rocketmq:server-4.3.2#创建broker容器
/data/rmq-data/rmqbroker/conf/broker.conf:/etc/rocketmq/broker.conf
/data/rmq-data/rmqbroker/logs:/opt/logs
/data/rmq-data/rmqbroker/store:/opt/store
foxiswho/rocketmq:broker-4.3.2#启动容器
enablePropertyFiltertrue部署RocketMQ的管理工具
UI管理工具rocketmq-console,项目地址https://github.com/apache/rocketmq-externals/tree/master/rocketmq-console
apacherocketmq/rocketmq-console:2.0.0#创建并启动容器
JAVA_OPTS-Drocketmq.config.namesrvAddr8.140.130.91:9876
-Drocketmq.config.isVIPChannelfalse
apacherocketmq/rocketmq-console:2.0.0访问http://8.140.130.91:8082/
org.apache.rocketmq.client.producer.DefaultMQProducer;public
Exception{//设置NameServer地址DefaultMQProducer
DefaultMQProducer(test-group);//设置producer
的NameServerAddressproducer.setNamesrvAddr(8.140.130.91:9876);//启动NameServerproducer.start();/**
*/producer.createTopic(broker_haoke_im,test_topic,8);System.out.println(topic创建成功);producer.shutdown();}
值说明Topicnull必填线下环境不需要申请线上环境需要申请后才能使用Bodynull必填二进制形式序列化由应用决定Producer
会延时特定的时间才会被消费WaitStoreMsgOKTRUE选填表示消息是否在服务器落盘后才返回应答。
org.apache.rocketmq.client.producer.DefaultMQProducer;
org.apache.rocketmq.client.producer.SendResult;
org.apache.rocketmq.common.message.Message;public
DefaultMQProducer(test-group);producer.setNamesrvAddr(8.140.130.91:9876);producer.start();String
Message(test_topic,test,msgStr.getBytes(UTF-8));SendResult
producer.send(message);System.out.println(result);System.out.println(消息状态
result.getSendStatus());System.out.println(消息id
result.getMsgId());System.out.println(消息queue
result.getMessageQueue());System.out.println(消息offset
result.getQueueOffset());producer.shutdown();}
org.apache.rocketmq.client.producer.DefaultMQProducer;
org.apache.rocketmq.client.producer.SendCallback;
org.apache.rocketmq.client.producer.SendResult;
org.apache.rocketmq.common.message.Message;public
DefaultMQProducer(test-group);producer.setNamesrvAddr(8.140.130.91:9876);producer.start();String
Message(test_topic,test,msgStr.getBytes(UTF-8));producer.send(message,
{System.out.println(result);System.out.println(消息状态
result.getSendStatus());System.out.println(消息id
result.getMsgId());System.out.println(消息queue
result.getMessageQueue());System.out.println(消息offset
result.getQueueOffset());}Overridepublic
{System.out.println(消息发送失败);}});//
producer.shutdown()要注释掉否则发送失败。
原因是异步发送还未来得及发送就被关闭了//producer.shutdown();}
org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
org.apache.rocketmq.common.message.MessageExt;import
java.io.UnsupportedEncodingException;
DefaultMQPushConsumer(test-group);consumer.setNamesrvAddr(8.140.130.91:9876);//订阅topic接收此topic下的所有消息consumer.subscribe(test_topic,*);consumer.registerMessageListener(new
{e.printStackTrace();}}System.out.println(收到消息-msgs);/**
ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});consumer.start();}
Message(test_topic,add,msgStr.getBytes(UTF-8));#消费者
consumer.subscribe(test_topic,add);
consumer.subscribe(test_topic,add
org.apache.rocketmq.client.producer.DefaultMQProducer;
org.apache.rocketmq.client.producer.SendResult;
org.apache.rocketmq.common.message.Message;/***
example-roketmq-com.rocketmq.filter*/
DefaultMQProducer(test-group);producer.setNamesrvAddr(8.140.130.91:9876);producer.start();String
Message(test_topic,test,msgStr.getBytes(UTF-8));msg.putUserProperty(age,18);msg.putUserProperty(sex,女);SendResult
producer.send(msg);System.out.println(消息状态result.getSendStatus());System.out.println(消息id
result.getMsgId());System.out.println(消息queueresult.getMessageQueue());System.out.println(消息offsetresult.getQueueOffset());producer.shutdown();}
org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
org.apache.rocketmq.client.consumer.MessageSelector;
org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
org.apache.rocketmq.client.exception.MQClientException;
org.apache.rocketmq.common.message.MessageExt;import
java.io.UnsupportedEncodingException;
DefaultMQPushConsumer(test-group);consumer.setNamesrvAddr(8.140.130.91:9876);consumer.subscribe(test_topic,
sex女));consumer.registerMessageListener(new
{e.printStackTrace();}}System.out.println(收到消息-msgs);return
ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});consumer.start();}
Message(test_topic,test,msgStr.getBytes(UTF-8));
msg.putUserProperty(sex,女);可以接收到消息
生产者发送的顺序消息都要放在同一消息队列中才能保证被顺序取出消费者接收的顺序消息需要从同一队列中获取
org.apache.rocketmq.client.producer.DefaultMQProducer;
org.apache.rocketmq.client.producer.SendResult;
org.apache.rocketmq.common.message.Message;public
DefaultMQProducer(test-group);producer.setNamesrvAddr(8.140.130.91:9876);producer.start();for
10;//生产10个订单的消息,每个订单10条消息String
Message(test_topic,ORDER_MSG,msgStr.getBytes(UTF-8));/**
producer.send(message,(mqs,msg,arg)-{//匿名函数的作用为选择消息队列的idInteger
mqs.get(index);},//arg与orderId对应orderId);System.out.println(sendResult);}producer.shutdown();}
Exception{DefaultMQPushConsumer
DefaultMQPushConsumer(test-order-group);consumer.setNamesrvAddr(8.140.130.91:9876);consumer.subscribe(test_order_topic,*);consumer.registerMessageListener(new
{System.out.println(Thread.currentThread().getName()
ConsumeOrderlyStatus.SUCCESS;}});consumer.start();}
}可见订单id为3的消息会存入同一消息队列故在同一消息队列的消息可被同一消费线程监听
基于单个JVM数据库分库分表基于多个JVM服务拆分基于多JVM服务拆分且数据库分库分表
消息系统暂时不能投递的消息发送方将消息发送到了MQ服务端。
MQ服务端未收到生产者对消息的二次确认此时该消息被标记为
由于网络闪断、生产者应用重启等原因导致某条事务消息的二次确认丢失MQ服务端发现某条消息长期处于
Server将消息持久化成功后向发送方ACK确认消息已经发送成功此时消息为
Exception{TransactionMQProducer
TransactionMQProducer(test_transaction_producer);producer.setNamesrvAddr(8.140.130.91:9876);//设置事务监听器producer.setTransactionListener(new
TransactionImpl());producer.start();//发送消息Message
Message(pay_topic,用户A给用户B转钱.getBytes(UTF-8));producer.sendMessageInTransaction(message,null);Thread.sleep(99999);producer.shutdown();}
executeLocalTransaction(Message
{Thread.sleep(500);System.out.println(用户A账户减500);//
System.out.println(1/0);System.out.println(用户B账户加500元.);Thread.sleep(800);//二次提交确认STATE_MAP.put(msg.getTransactionId(),LocalTransactionState.COMMIT_MESSAGE);return
LocalTransactionState.COMMIT_MESSAGE;}
{e.printStackTrace();}//回滚STATE_MAP.put(msg.getTransactionId(),
LocalTransactionState.ROLLBACK_MESSAGE);return
LocalTransactionState.ROLLBACK_MESSAGE;}/***
checkLocalTransaction(MessageExt
STATE_MAP.get(msg.getTransactionId());}
DefaultMQPushConsumer(test_transaction_consumer);consumer.setNamesrvAddr(8.140.130.91:9876);//订阅topic接收消息consumer.subscribe(pay_topic,*);consumer.registerMessageListener(new
ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});consumer.start();}
executeLocalTransaction(Message
{System.out.println(用户A账户减500);Thread.sleep(500);//
System.out.println(1/0);System.out.println(用户B账户加500元.);Thread.sleep(800);//二次提交确认STATE_MAP.put(msg.getTransactionId(),LocalTransactionState.COMMIT_MESSAGE);return
LocalTransactionState.COMMIT_MESSAGE;}
{e.printStackTrace();}//回滚STATE_MAP.put(msg.getTransactionId(),
LocalTransactionState.ROLLBACK_MESSAGE);return
LocalTransactionState.ROLLBACK_MESSAGE;}/***
checkLocalTransaction(MessageExt
STATE_MAP.get(msg.getTransactionId()));return
STATE_MAP.get(msg.getTransactionId());}
push模式客户端与服务端建立连接后当服务端有消息将消息推送到客户端pull模式客户端不断的轮询请求服务端来获取新的而消息
push模式需要消息系统与消费端之间建立长连接对消息系统是很大的负担所以在具体实现时都采用消费端主动拉取的方式即consumer轮询从broker拉取消息
将轮询过程都封装了并注册MessageListener监听器取到消息后唤醒MessageListener监听器的consumeMessage()来消费对用户而言感觉消息是被推送来的。
Pull取消息过程需要自己写首先从目标topic中拿到MessageQueue集合并遍历然后针对每个MessageQueue批量取消息。
一次Pull都要记录该队列的offset,知道去完MessageQueue再换另一个
长轮询长连接轮询客户端像传统轮询一样从服务端请求数据服务端会阻塞请求不会立刻返回直到有数据或超时才返回给客户端然后关闭连接客户端处理完响应信息后再向服务器发送新的请求
DefaultMQPushConsumer实现了自动保存offset值及多个consumer的负载均衡
DefaultMQPushConsumer(HAOKE_IM);通过
将多个consumer组合在一起会存在消息的分配问题消息是发送到组还是每个消费者
同一个ConsumerGroup里的每个Consumer只消费所订阅消息的一部分内容同一个ConsumerGroup里所有消费的内容合起来才是所订阅Topic内容的整体从而达到负载均衡的目的
同一个ConsumerGroup里的每个Consumer都能消费到所订阅Topic的全部消息一个消息会被分发多次被多个Consumer消费
consumer.setMessageModel(MessageModel.CLUSTERING);
consumer.setMessageModel(MessageModel.BROADCASTING);重复消息的解决方案
保证每条消息都有唯一编号且保证消息处理成功与去重的日志同时出现
利用一张日志表来记录已经处理成功的消息的ID如果新到的消息ID已经在日志表中那么就不再处理这条消息
如果由消息系统来实现的话肯定会对消息系统的吞吐量和高可用有影响所以最好还是由业务端自己处理消息重复的问题这也是
在RocketMQ中消息数据是保存在磁盘文件中的使用RocketMQ尽可能保证顺序写入比随机写入效率高很多
是一个逻辑队列存储了这个Queue在CommitLog中的其实offset、log大小和MessageTag的hashcode
每次读取消息队列先读取ConsumerQueue然后再通过consumerQueue中拿到消息主体
RocketMQ为提高性能会尽可能保证磁盘的顺序读写。
消息通过Producer写入RocketMQ的时候有两种写磁盘方式分别是同步刷盘与异步刷盘
在返回写成功状态时消息已经写入磁盘执行流程消息写入内存的PAGECACHE后立刻通知刷盘线程刷盘等待刷盘完成刷盘线程执行完成后唤醒等待的线程返回消息写成功的状态
在返回写成功状态时消息可能只是被写入内存的PAGECACHE写操作的返回快吞吐量大当内存里的消息积累到一定程度统一触发写磁盘动作快速写入
在消息的发送和消费过程中都有可能出现错误如网络异常等出现了错误就需要进行错误重试这种消息的重试分为
producer.setRetryTimesWhenSendFailed(3);//
1000);只有同步生产者才会进行错误重试。
只有特定异常才会重试设置的超时时间小于实际执行时间则不会进行重试
this.defaultMQProducer.getRetryTimesWhenSendFailed()
ResponseCode.TOPIC_NOT_EXIST:case
ResponseCode.SERVICE_NOT_AVAILABLE:case
ResponseCode.NO_PERMISSION:case
ResponseCode.NOT_IN_CURRENT_UNIT:continue;}}
消息正常到了消费者端处理失败发生异常。
eg反序列化失败消息数据本身无法处理
org.apache.rocketmq.client.consumer.listener;public
consumption*/CONSUME_SUCCESS,/***
DefaultMQPushConsumer(test_consumer_group);consumer.setNamesrvAddr(8.140.130.91:9876);//
订阅topic接收此Topic下的所有消息consumer.subscribe(test_error_topic,
*);consumer.registerMessageListener(new
msgs,ConsumeConcurrentlyContext
{e.printStackTrace();}}System.out.println(收到消息-
msgs);if(msgs.get(0).getReconsumeTimes()
ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}return
ConsumeConcurrentlyStatus.RECONSUME_LATER;}});consumer.start();}
风险较大一旦Broker重启或者宕机会导致整个服务不可用只做开发环境
一个集群无Slave全是Master例如2个Master或者3个Master单台机器宕机这台机器上未被消费的消息在机器恢复之前不可订阅消息的实时性受到影响
每个Master配置一个Slave有多个Master-Slave对HA双机集群系统采用异步复制方式主备有短暂消息延迟毫秒级优点即使磁盘损坏丢失的消息非常少实时性不会收到影响消费者仍可从Slave消费此过程对应用透明不需人工干预性能同多Master模式一样缺点Master宕机或磁盘损坏会丢失少量消息
每个Master配置一个Slave有多个Master-Slave对HA双机集群系统采用同步双写方式主备都写成功向应用返回成功优点数据与服务无单点Master宕机情况下消息无延迟服务可用性和数据可用性非常高缺点性能比异步复制模式低
/data/rmq-data/rmqserver01/logs:/opt/logs
/data/rmq-data/rmqserver01/store:/opt/store
foxiswho/rocketmq:server-4.3.2#nameserver2
/data/rmq-data/rmqserver02/logs:/opt/logs
/data/rmq-data/rmqserver02/store:/opt/store
foxiswho/rocketmq:server-4.3.2搭建broker(2master)
namesrvAddr8.140.130.91:9876;8.140.130.91:9877
/data/rmq-data/rmqbroker01/conf/broker.conf:/etc/rocketmq/broker.conf
/data/rmq-data/rmqbroker01/logs:/opt/logs
/data/rmq-data/rmqbroker01/store:/opt/store
foxiswho/rocketmq:broker-4.3.2brokerId0表示主0表示Slave
namesrvAddr8.140.130.91:9876;8.140.130.91:9877
/data/rmq-data/rmqbroker02/conf/broker.conf:/etc/rocketmq/broker.conf
/data/rmq-data/rmqbroker02/logs:/opt/logs
/data/rmq-data/rmqbroker02/store:/opt/store
foxiswho/rocketmq:broker-4.3.2搭建从broker(slave)
namesrvAddr8.140.130.91:9876;8.140.130.91:9877
/data/rmq-data/rmqbroker03/conf/broker.conf:/etc/rocketmq/broker.conf
/data/rmq-data/rmqbroker03/logs:/opt/logs
/data/rmq-data/rmqbroker03/store:/opt/store
foxiswho/rocketmq:broker-4.3.2#slave
namesrvAddr8.140.130.91:9876;8.140.130.91:9877
/data/rmq-data/rmqbroker04/conf/broker.conf:/etc/rocketmq/broker.conf
/data/rmq-data/rmqbroker04/logs:/opt/logs
/data/rmq-data/rmqbroker04/store:/opt/store
foxiswho/rocketmq:broker-4.3.2#启动容器
DefaultMQProducer(test_cluster_group);producer.setNamesrvAddr(8.140.130.91:9876;8.140.130.91:9877);producer.start();String
Message(test_cluster_topic,CLUSTER,msgStr.getBytes(UTF-8));SendResult
producer.send(message);System.out.println(result);System.out.println(消息状态
result.getSendStatus());System.out.println(消息id
result.getMsgId());System.out.println(消息queue
result.getMessageQueue());System.out.println(消息offset
result.getQueueOffset());producer.shutdown();}
DefaultMQPushConsumer(test_cluster_group);consumer.setNamesrvAddr(8.140.130.91:9876;8.140.130.91:9877);//订阅topopic接收此topic下的所有消息consumer.subscribe(test_cluster_topic,*);consumer.registerMessageListener(new
{e.printStackTrace();}}System.out.println(收到消息-msgs);/**
ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});consumer.start();}
由于rocketMQ没有发布到Mven中央仓库需要自行下载源码并载入到本地Maven仓库
https://hub.fastgit.org/apache/rocketmq-spring#进入源码目录执行
parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.4.3/version
/parentdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.apache.rocketmq/groupIdartifactIdrocketmq-spring-boot-starter/artifactIdversion2.0.0/version/dependencydependencygroupIdorg.apache.rocketmq/groupIdartifactIdrocketmq-client/artifactIdversion4.3.2/version/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdscopetest/scope/dependency
/dependenciesbuildpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdversion3.2/versionconfigurationsource1.8/sourcetarget1.8/targetencodingUTF-8/encoding/configuration/plugin/plugins
spring.rocketmq.nameServer8.140.130.91:9876
spring.rocketmq.producer.grouptest_spring_producer_group基本使用
{//注入rocketmq模板Autowiredprivate
msg){this.rocketMQTemplate.convertAndSend(topic,msg);}
com.rocketmq;SpringBootApplication
{SpringApplication.run(MyApplication.class,args);}
org.springframework.beans.factory.annotation.Autowired;
org.springframework.boot.test.context.SpringBootTest;
org.springframework.test.context.junit4.SpringRunner;RunWith(SpringRunner.class)
消息;this.producer.sendMsg(test_spring_topic,msg);System.out.println(发送成功!);}}消费者消费消息
org.apache.rocketmq.spring.annotation.ConsumeMode;
org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
org.apache.rocketmq.spring.core.RocketMQListener;
org.springframework.stereotype.Component;Component
test_spring_topic,consumerGroup
test_spring_consumer_group,selectorExpression
{System.out.println(收到消息-msg);}
com.rocketmq.spring.transaction;Component
MessageBuilder.withPayload(msg).build();//此处的txProducerGroup与事务监听器的RocketMQTransactionListener(txProducerGroup
)一致this.rocketMQTemplate.sendMessageInTransaction(test_tx_producer_group,topic,message,null);System.out.println(消息发送成功);}
com.rocketmq.spring.transaction;RocketMQTransactionListener(txProducerGroup
RocketMQLocalTransactionListener
MapString,RocketMQLocalTransactionState
executeLocalTransaction(Message
message.getHeaders().get(RocketMQHeaders.TRANSACTION_ID);try
{System.out.println(执行操作1);Thread.sleep(500L);System.out.println(执行操作2);Thread.sleep(500L);STATE_MAP.put(transactionId,RocketMQLocalTransactionState.COMMIT);return
RocketMQLocalTransactionState.COMMIT;}catch
e){e.printStackTrace();}STATE_MAP.put(transactionId,RocketMQLocalTransactionState.ROLLBACK);return
RocketMQLocalTransactionState.ROLLBACK;}/***
message.getHeaders().get(RocketMQHeaders.TRANSACTION_ID);System.out.println(回查消息-transactionId
STATE_MAP.get(transactionId));return
testSendTransactionMsg(){String
事务消息测试!;this.transactionProducer.sendMsg(test_spring_transaction_topic,msg);System.out.println(发送成功);
com.rocketmq.spring.transaction;Component
test_spring_transaction_topic,consumeMode
ConsumeMode.CONCURRENTLY,selectorExpression
executeLocalTransaction(Message
message.getHeaders().get(RocketMQHeaders.TRANSACTION_ID);try
{System.out.println(执行操作1);Thread.sleep(500L);System.out.println(执行操作2);Thread.sleep(500L);STATE_MAP.put(transactionId,RocketMQLocalTransactionState.COMMIT);return
RocketMQLocalTransactionState.UNKNOWN;}catch
e){e.printStackTrace();}STATE_MAP.put(transactionId,RocketMQLocalTransactionState.ROLLBACK);return
RocketMQLocalTransactionState.ROLLBACK;
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback