谷歌SEO

谷歌SEO

Products

当前位置:首页 > 谷歌SEO >

传统企业如何评估电商网站建设的成本?

96SEO 2026-02-19 10:31 0


Q概念用途特性安装RocketMQ掌握RocketMQ的api使用对producer、consumer进行详解了解RocketMQ的存储特点

传统企业如何评估电商网站建设的成本?

简介及相关概念JavaAPISpringBoot整合RocketMQ消息的顺序收发消息系统的事务、存储、重试策略消息系统的集群

RocketMQ

阿里中间件Notify用于交易核心信息的流转2010年B2B开始大规模使用ActiveMQ作为消息内核急需支持顺序消息、拥有海量消息堆积能力的消息中间件——MetaQ

1.0

年MetaQ发展到了3.0版本抽象除了通用的消息引擎RorcketMQ2015年RocketMQ进过双十一在可用性可靠性和稳定性等方面都有出色表现。

阿里消息中间件基于RocketMQ退出Aliware

MQ1.0开始为阿里云上的企业提供消息服务2016年RocketMQ进入Apache孵化

Producer

Group一类Producer的集合名称这类Producer通常发送同一类消息且发送逻辑一致

Consumer

Group一类Consumer的集合名称这类Producer通常发送同一类消息且发送逻辑一致

Broker

RocketMQ的核心消息的发送、接收、高可用等需要定时发送自身情况到NameServer,默认10s发送一次超过2分钟会认为该broker失效

NameServer

不同类型的消息以不同的Topic名称进行区分如User、Order等Message

Queue

下载地址https://archive.apache.org/dist/rocketmq/4.3.2/rocketmq-all-4.3.2-bin-release.zip

/opt

rocketmq-all-4.3.2-bin-release.zip

rocketmq-all-4.3.2-bin-release/#

启动nameserver

os::commit_memory(0x00000005c0000000,

8589934592,

(errno12)启动错误因为RocketMQ的配置默认是生产环境的配置设置jvm的内存值比较大需要调整默认值

bin/

broker[iZ2zeg4pktzjhp9h7wt6doZ,

172.17.0.1:10911]

/opt/rocketmq-all-4.3.2-bin-release/bin

tools.sh

org.apache.rocketmq.example.quickstart.Producer接收消息测试

tools.sh

org.apache.rocketmq.example.quickstart.Consumerjava

api测试

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

/build测试代码

org.apache.rocketmq.client.exception.MQBrokerException;

import

org.apache.rocketmq.client.exception.MQClientException;

import

org.apache.rocketmq.client.producer.DefaultMQProducer;

import

org.apache.rocketmq.client.producer.SendResult;

import

org.apache.rocketmq.common.message.Message;

import

org.apache.rocketmq.remoting.common.RemotingHelper;

import

org.apache.rocketmq.remoting.exception.RemotingException;import

java.io.UnsupportedEncodingException;public

class

DefaultMQProducer(test-group);//specify

name

addressproducer.setNamesrvAddr(8.140.130.91:9876);//Lanuch

the

Message(TopicTest1,/*topic*/TAGA,/*tag*/(Hello

RocketMQ

i).getBytes(RemotingHelper.DEFAULT_CHARSET)/*message

body*/);//Call

producer.send(msg);System.out.printf(%s%n,

sendResult);}//Shut

broker的ip地址是172.17.0.1,为私有ip所以不可访问

/opt/rocketmq-all-4.3.2-bin-release/conf

vim

broker.confbrokerIP18.140.130.91

brokerNamebroker_haoke_im#启动broker通过

指定配置文件

/opt/rocketmq-all-4.3.2-bin-release/

bin/mqbroker

/opt/rocketmq-all-4.3.2-bin-release/conf/broker.confAPI测试成功

#拉取镜像

foxiswho/rocketmq:broker-4.3.2#创建nameserver容器

docker

/data/rmq-data/rmqserver/logs:/opt/logs

/data/rmq-data/rmqserver/store:/opt/store

foxiswho/rocketmq:server-4.3.2#创建broker容器

#10911

/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#启动容器

docker

enablePropertyFiltertrue部署RocketMQ的管理工具

UI管理工具rocketmq-console,项目地址https://github.com/apache/rocketmq-externals/tree/master/rocketmq-console

#拉取镜像

apacherocketmq/rocketmq-console:2.0.0#创建并启动容器

docker

JAVA_OPTS-Drocketmq.config.namesrvAddr8.140.130.91:9876

-Drocketmq.config.isVIPChannelfalse

8082:8080

apacherocketmq/rocketmq-console:2.0.0访问http://8.140.130.91:8082/

Java

org.apache.rocketmq.client.producer.DefaultMQProducer;public

class

Exception{//设置NameServer地址DefaultMQProducer

producer

DefaultMQProducer(test-group);//设置producer

的NameServerAddressproducer.setNamesrvAddr(8.140.130.91:9876);//启动NameServerproducer.start();/**

创建topic*

*/producer.createTopic(broker_haoke_im,test_topic,8);System.out.println(topic创建成功);producer.shutdown();}

}发送消息

值说明Topicnull必填线下环境不需要申请线上环境需要申请后才能使用Bodynull必填二进制形式序列化由应用决定Producer

Consumer

会延时特定的时间才会被消费WaitStoreMsgOKTRUE选填表示消息是否在服务器落盘后才返回应答。

package

org.apache.rocketmq.client.producer.DefaultMQProducer;

import

org.apache.rocketmq.client.producer.SendResult;

import

org.apache.rocketmq.common.message.Message;public

class

DefaultMQProducer(test-group);producer.setNamesrvAddr(8.140.130.91:9876);producer.start();String

msgStr

Message(test_topic,test,msgStr.getBytes(UTF-8));SendResult

result

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;

import

org.apache.rocketmq.client.producer.SendCallback;

import

org.apache.rocketmq.client.producer.SendResult;

import

org.apache.rocketmq.common.message.Message;public

class

DefaultMQProducer(test-group);producer.setNamesrvAddr(8.140.130.91:9876);producer.start();String

msgStr

Message(test_topic,test,msgStr.getBytes(UTF-8));producer.send(message,

new

{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

void

{System.out.println(消息发送失败);}});//

producer.shutdown()要注释掉否则发送失败。

原因是异步发送还未来得及发送就被关闭了//producer.shutdown();}

}消费信息

org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;

import

org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;

import

org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;

import

org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;

import

org.apache.rocketmq.common.message.MessageExt;import

java.io.UnsupportedEncodingException;

import

DefaultMQPushConsumer(test-group);consumer.setNamesrvAddr(8.140.130.91:9876);//订阅topic接收此topic下的所有消息consumer.subscribe(test_topic,*);consumer.registerMessageListener(new

msgs,

{e.printStackTrace();}}System.out.println(收到消息-msgs);/**

CONSUME_SUCCESS

ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});consumer.start();}

}测试接收历史消息

Message(test_topic,add,msgStr.getBytes(UTF-8));#消费者

//完整匹配

consumer.subscribe(test_topic,add);

//或匹配

consumer.subscribe(test_topic,add

类似与SQL

org.apache.rocketmq.client.producer.DefaultMQProducer;

import

org.apache.rocketmq.client.producer.SendResult;

import

org.apache.rocketmq.common.message.Message;/***

author

example-roketmq-com.rocketmq.filter*/

public

DefaultMQProducer(test-group);producer.setNamesrvAddr(8.140.130.91:9876);producer.start();String

msgStr

Message(test_topic,test,msgStr.getBytes(UTF-8));msg.putUserProperty(age,18);msg.putUserProperty(sex,女);SendResult

result

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;

import

org.apache.rocketmq.client.consumer.MessageSelector;

import

org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;

import

org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;

import

org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;

import

org.apache.rocketmq.client.exception.MQClientException;

import

org.apache.rocketmq.common.message.MessageExt;import

java.io.UnsupportedEncodingException;

import

DefaultMQPushConsumer(test-group);consumer.setNamesrvAddr(8.140.130.91:9876);consumer.subscribe(test_topic,

AND

sex女));consumer.registerMessageListener(new

msgs,

{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;

import

org.apache.rocketmq.client.producer.SendResult;

import

org.apache.rocketmq.common.message.Message;public

class

DefaultMQProducer(test-group);producer.setNamesrvAddr(8.140.130.91:9876);producer.start();for

(int

10;//生产10个订单的消息,每个订单10条消息String

msgStr

Message(test_topic,ORDER_MSG,msgStr.getBytes(UTF-8));/**

public

producer.send(message,(mqs,msg,arg)-{//匿名函数的作用为选择消息队列的idInteger

(Integer)

mqs.get(index);},//arg与orderId对应orderId);System.out.println(sendResult);}producer.shutdown();}

}消费者

Exception{DefaultMQPushConsumer

consumer

DefaultMQPushConsumer(test-order-group);consumer.setNamesrvAddr(8.140.130.91:9876);consumer.subscribe(test_order_topic,*);consumer.registerMessageListener(new

ConsumeOrderlyStatus

{System.out.println(Thread.currentThread().getName()

msg.getQueueId()

ConsumeOrderlyStatus.SUCCESS;}});consumer.start();}

}可见订单id为3的消息会存入同一消息队列故在同一消息队列的消息可被同一消费线程监听

分布式事务分类

基于单个JVM数据库分库分表基于多个JVM服务拆分基于多JVM服务拆分且数据库分库分表

Half(Prepare)

消息系统暂时不能投递的消息发送方将消息发送到了MQ服务端。

MQ服务端未收到生产者对消息的二次确认此时该消息被标记为

暂不能投递状态

由于网络闪断、生产者应用重启等原因导致某条事务消息的二次确认丢失MQ服务端发现某条消息长期处于

发送方向MQ服务端发送消息

Server将消息持久化成功后向发送方ACK确认消息已经发送成功此时消息为

半消息

Exception{TransactionMQProducer

producer

TransactionMQProducer(test_transaction_producer);producer.setNamesrvAddr(8.140.130.91:9876);//设置事务监听器producer.setTransactionListener(new

TransactionImpl());producer.start();//发送消息Message

message

Message(pay_topic,用户A给用户B转钱.getBytes(UTF-8));producer.sendMessageInTransaction(message,null);Thread.sleep(99999);producer.shutdown();}

}本地事务处理

executeLocalTransaction(Message

msg,

{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;}

catch

{e.printStackTrace();}//回滚STATE_MAP.put(msg.getTransactionId(),

LocalTransactionState.ROLLBACK_MESSAGE);return

LocalTransactionState.ROLLBACK_MESSAGE;}/***

消息回查*

checkLocalTransaction(MessageExt

msg)

STATE_MAP.get(msg.getTransactionId());}

}消费者

DefaultMQPushConsumer(test_transaction_consumer);consumer.setNamesrvAddr(8.140.130.91:9876);//订阅topic接收消息consumer.subscribe(pay_topic,*);consumer.registerMessageListener(new

{Overridepublic

ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});consumer.start();}

}测试

executeLocalTransaction(Message

msg,

{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

return

LocalTransactionState.COMMIT_MESSAGE;}

catch

{e.printStackTrace();}//回滚STATE_MAP.put(msg.getTransactionId(),

LocalTransactionState.ROLLBACK_MESSAGE);return

LocalTransactionState.ROLLBACK_MESSAGE;}/***

消息回查*

checkLocalTransaction(MessageExt

msg)

STATE_MAP.get(msg.getTransactionId()));return

STATE_MAP.get(msg.getTransactionId());}

}Consumer

push模式客户端与服务端建立连接后当服务端有消息将消息推送到客户端pull模式客户端不断的轮询请求服务端来获取新的而消息

push模式需要消息系统与消费端之间建立长连接对消息系统是很大的负担所以在具体实现时都采用消费端主动拉取的方式即consumer轮询从broker拉取消息

将轮询过程都封装了并注册MessageListener监听器取到消息后唤醒MessageListener监听器的consumeMessage()来消费对用户而言感觉消息是被推送来的。

Pull取消息过程需要自己写首先从目标topic中拿到MessageQueue集合并遍历然后针对每个MessageQueue批量取消息。

一次Pull都要记录该队列的offset,知道去完MessageQueue再换另一个

长轮询长连接轮询客户端像传统轮询一样从服务端请求数据服务端会阻塞请求不会立刻返回直到有数据或超时才返回给客户端然后关闭连接客户端处理完响应信息后再向服务器发送新的请求

消息模式

DefaultMQPushConsumer实现了自动保存offset值及多个consumer的负载均衡

//设置组名

DefaultMQPushConsumer(HAOKE_IM);通过

groupname

将多个consumer组合在一起会存在消息的分配问题消息是发送到组还是每个消费者

集群模式默认

同一个ConsumerGroup里的每个Consumer只消费所订阅消息的一部分内容同一个ConsumerGroup里所有消费的内容合起来才是所订阅Topic内容的整体从而达到负载均衡的目的

广播模式

同一个ConsumerGroup里的每个Consumer都能消费到所订阅Topic的全部消息一个消息会被分发多次被多个Consumer消费

集群模式

consumer.setMessageModel(MessageModel.CLUSTERING);

广播模式

consumer.setMessageModel(MessageModel.BROADCASTING);重复消息的解决方案

生产者不断发送重复消息到消息系统

保证每条消息都有唯一编号且保证消息处理成功与去重的日志同时出现

利用一张日志表来记录已经处理成功的消息的ID如果新到的消息ID已经在日志表中那么就不再处理这条消息

如果由消息系统来实现的话肯定会对消息系统的吞吐量和高可用有影响所以最好还是由业务端自己处理消息重复的问题这也是

RocketMQ存储

在RocketMQ中消息数据是保存在磁盘文件中的使用RocketMQ尽可能保证顺序写入比随机写入效率高很多

Consume

是一个逻辑队列存储了这个Queue在CommitLog中的其实offset、log大小和MessageTag的hashcode

每次读取消息队列先读取ConsumerQueue然后再通过consumerQueue中拿到消息主体

同步刷盘和异步刷盘

RocketMQ为提高性能会尽可能保证磁盘的顺序读写。

消息通过Producer写入RocketMQ的时候有两种写磁盘方式分别是同步刷盘与异步刷盘

同步刷盘——安全性

在返回写成功状态时消息已经写入磁盘执行流程消息写入内存的PAGECACHE后立刻通知刷盘线程刷盘等待刷盘完成刷盘线程执行完成后唤醒等待的线程返回消息写成功的状态

异步刷盘——效率

在返回写成功状态时消息可能只是被写入内存的PAGECACHE写操作的返回快吞吐量大当内存里的消息积累到一定程度统一触发写磁盘动作快速写入

修改刷盘方式

在消息的发送和消费过程中都有可能出现错误如网络异常等出现了错误就需要进行错误重试这种消息的重试分为

consumer端重试

producer.setRetryTimesWhenSendFailed(3);//

发送消息,并且指定超时时间

1000);只有同步生产者才会进行错误重试。

只有特定异常才会重试设置的超时时间小于实际执行时间则不会进行重试

//设置发送总次数

this.defaultMQProducer.getRetryTimesWhenSendFailed()

1;for

ResponseCode.TOPIC_NOT_EXIST:case

ResponseCode.SERVICE_NOT_AVAILABLE:case

ResponseCode.NO_PERMISSION:case

ResponseCode.NOT_IN_CURRENT_UNIT:continue;}}

}consumer端重试

消息正常到了消费者端处理失败发生异常。

eg反序列化失败消息数据本身无法处理

消息状态

org.apache.rocketmq.client.consumer.listener;public

enum

consumption*/CONSUME_SUCCESS,/***

Failure

DefaultMQPushConsumer(test_consumer_group);consumer.setNamesrvAddr(8.140.130.91:9876);//

订阅topic接收此Topic下的所有消息consumer.subscribe(test_error_topic,

*);consumer.registerMessageListener(new

{Overridepublic

msgs,ConsumeConcurrentlyContext

context)

{e.printStackTrace();}}System.out.println(收到消息-

msgs);if(msgs.get(0).getReconsumeTimes()

3){//

ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}return

ConsumeConcurrentlyStatus.RECONSUME_LATER;}});consumer.start();}

timeout

风险较大一旦Broker重启或者宕机会导致整个服务不可用只做开发环境

多Master

一个集群无Slave全是Master例如2个Master或者3个Master单台机器宕机这台机器上未被消费的消息在机器恢复之前不可订阅消息的实时性受到影响

多Master多Slave异步复制

每个Master配置一个Slave有多个Master-Slave对HA双机集群系统采用异步复制方式主备有短暂消息延迟毫秒级优点即使磁盘损坏丢失的消息非常少实时性不会收到影响消费者仍可从Slave消费此过程对应用透明不需人工干预性能同多Master模式一样缺点Master宕机或磁盘损坏会丢失少量消息

多Master多Slave,同步双写

每个Master配置一个Slave有多个Master-Slave对HA双机集群系统采用同步双写方式主备都写成功向应用返回成功优点数据与服务无单点Master宕机情况下消息无延迟服务可用性和数据可用性非常高缺点性能比异步复制模式低

搭建2m2s集群

/data/rmq-data/rmqserver01/logs:/opt/logs

/data/rmq-data/rmqserver01/store:/opt/store

foxiswho/rocketmq:server-4.3.2#nameserver2

docker

/data/rmq-data/rmqserver02/logs:/opt/logs

/data/rmq-data/rmqserver02/store:/opt/store

foxiswho/rocketmq:server-4.3.2搭建broker(2master)

#broker01配置文件

namesrvAddr8.140.130.91:9876;8.140.130.91:9877

brokerNamebroker01

/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

单位——h

namesrvAddr8.140.130.91:9876;8.140.130.91:9877

brokerNamebroker02

/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)

#slave

namesrvAddr8.140.130.91:9876;8.140.130.91:9877

brokerNamebroker01

/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

broker02配置文件

namesrvAddr8.140.130.91:9876;8.140.130.91:9877

brokerNamebroker02

/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#启动容器

docker

DefaultMQProducer(test_cluster_group);producer.setNamesrvAddr(8.140.130.91:9876;8.140.130.91:9877);producer.start();String

msgStr

Message(test_cluster_topic,CLUSTER,msgStr.getBytes(UTF-8));SendResult

result

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

msgs,

{e.printStackTrace();}}System.out.println(收到消息-msgs);/**

CONSUME_SUCCESS

ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});consumer.start();}

下载依赖

由于rocketMQ没有发布到Mven中央仓库需要自行下载源码并载入到本地Maven仓库

#源码地址

https://hub.fastgit.org/apache/rocketmq-spring#进入源码目录执行

mvn

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

spring.rocketmq.nameServer8.140.130.91:9876

spring.rocketmq.producer.grouptest_spring_producer_group基本使用

生产者发送消息

{//注入rocketmq模板Autowiredprivate

RocketMQTemplate

msg){this.rocketMQTemplate.convertAndSend(topic,msg);}

}启动类

com.rocketmq;SpringBootApplication

public

{SpringApplication.run(MyApplication.class,args);}

}测试生产消息

org.springframework.beans.factory.annotation.Autowired;

import

org.springframework.boot.test.context.SpringBootTest;

import

org.springframework.test.context.junit4.SpringRunner;RunWith(SpringRunner.class)

SpringBootTest

消息;this.producer.sendMsg(test_spring_topic,msg);System.out.println(发送成功!);}}消费者消费消息

package

org.apache.rocketmq.spring.annotation.ConsumeMode;

import

org.apache.rocketmq.spring.annotation.RocketMQMessageListener;

import

org.apache.rocketmq.spring.core.RocketMQListener;

import

org.springframework.stereotype.Component;Component

test_spring_topic,consumerGroup

test_spring_consumer_group,selectorExpression

*,consumeMode

{System.out.println(收到消息-msg);}

}事务消息

com.rocketmq.spring.transaction;Component

public

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

public

RocketMQLocalTransactionListener

{private

MapString,RocketMQLocalTransactionState

STATE_MAP

executeLocalTransaction(Message

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

(Exception

e){e.printStackTrace();}STATE_MAP.put(transactionId,RocketMQLocalTransactionState.ROLLBACK);return

RocketMQLocalTransactionState.ROLLBACK;}/***

消息回查**

message.getHeaders().get(RocketMQHeaders.TRANSACTION_ID);System.out.println(回查消息-transactionId

transactionId,state

STATE_MAP.get(transactionId));return

}消息生产测试

testSendTransactionMsg(){String

msg

事务消息测试!;this.transactionProducer.sendMsg(test_spring_transaction_topic,msg);System.out.println(发送成功);

}消费者测试

com.rocketmq.spring.transaction;Component

test_spring_transaction_topic,consumeMode

ConsumeMode.CONCURRENTLY,selectorExpression

*,consumerGroup

executeLocalTransaction(Message

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

(Exception

e){e.printStackTrace();}STATE_MAP.put(transactionId,RocketMQLocalTransactionState.ROLLBACK);return

RocketMQLocalTransactionState.ROLLBACK;



SEO优化服务概述

作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。

百度官方合作伙伴 白帽SEO技术 数据驱动优化 效果长期稳定

SEO优化核心服务

网站技术SEO

  • 网站结构优化 - 提升网站爬虫可访问性
  • 页面速度优化 - 缩短加载时间,提高用户体验
  • 移动端适配 - 确保移动设备友好性
  • HTTPS安全协议 - 提升网站安全性与信任度
  • 结构化数据标记 - 增强搜索结果显示效果

内容优化服务

  • 关键词研究与布局 - 精准定位目标关键词
  • 高质量内容创作 - 原创、专业、有价值的内容
  • Meta标签优化 - 提升点击率和相关性
  • 内容更新策略 - 保持网站内容新鲜度
  • 多媒体内容优化 - 图片、视频SEO优化

外链建设策略

  • 高质量外链获取 - 权威网站链接建设
  • 品牌提及监控 - 追踪品牌在线曝光
  • 行业目录提交 - 提升网站基础权威
  • 社交媒体整合 - 增强内容传播力
  • 链接质量分析 - 避免低质量链接风险

SEO服务方案对比

服务项目 基础套餐 标准套餐 高级定制
关键词优化数量 10-20个核心词 30-50个核心词+长尾词 80-150个全方位覆盖
内容优化 基础页面优化 全站内容优化+每月5篇原创 个性化内容策略+每月15篇原创
技术SEO 基本技术检查 全面技术优化+移动适配 深度技术重构+性能优化
外链建设 每月5-10条 每月20-30条高质量外链 每月50+条多渠道外链
数据报告 月度基础报告 双周详细报告+分析 每周深度报告+策略调整
效果保障 3-6个月见效 2-4个月见效 1-3个月快速见效

SEO优化实施流程

我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:

1

网站诊断分析

全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。

2

关键词策略制定

基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。

3

技术优化实施

解决网站技术问题,优化网站结构,提升页面速度和移动端体验。

4

内容优化建设

创作高质量原创内容,优化现有页面,建立内容更新机制。

5

外链建设推广

获取高质量外部链接,建立品牌在线影响力,提升网站权威度。

6

数据监控调整

持续监控排名、流量和转化数据,根据效果调整优化策略。

SEO优化常见问题

SEO优化一般需要多长时间才能看到效果?
SEO是一个渐进的过程,通常需要3-6个月才能看到明显效果。具体时间取决于网站现状、竞争程度和优化强度。我们的标准套餐一般在2-4个月内开始显现效果,高级定制方案可能在1-3个月内就能看到初步成果。
你们使用白帽SEO技术还是黑帽技术?
我们始终坚持使用白帽SEO技术,遵循搜索引擎的官方指南。我们的优化策略注重长期效果和可持续性,绝不使用任何可能导致网站被惩罚的违规手段。作为百度官方合作伙伴,我们承诺提供安全、合规的SEO服务。
SEO优化后效果能持续多久?
通过我们的白帽SEO策略获得的排名和流量具有长期稳定性。一旦网站达到理想排名,只需适当的维护和更新,效果可以持续数年。我们提供优化后维护服务,确保您的网站长期保持竞争优势。
你们提供SEO优化效果保障吗?
我们提供基于数据的SEO效果承诺。根据服务套餐不同,我们承诺在约定时间内将核心关键词优化到指定排名位置,或实现约定的自然流量增长目标。所有承诺都会在服务合同中明确约定,并提供详细的KPI衡量标准。

SEO优化效果数据

基于我们服务的客户数据统计,平均优化效果如下:

+85%
自然搜索流量提升
+120%
关键词排名数量
+60%
网站转化率提升
3-6月
平均见效周期

行业案例 - 制造业

  • 优化前:日均自然流量120,核心词无排名
  • 优化6个月后:日均自然流量950,15个核心词首页排名
  • 效果提升:流量增长692%,询盘量增加320%

行业案例 - 电商

  • 优化前:月均自然订单50单,转化率1.2%
  • 优化4个月后:月均自然订单210单,转化率2.8%
  • 效果提升:订单增长320%,转化率提升133%

行业案例 - 教育

  • 优化前:月均咨询量35个,主要依赖付费广告
  • 优化5个月后:月均咨询量180个,自然流量占比65%
  • 效果提升:咨询量增长414%,营销成本降低57%

为什么选择我们的SEO服务

专业团队

  • 10年以上SEO经验专家带队
  • 百度、Google认证工程师
  • 内容创作、技术开发、数据分析多领域团队
  • 持续培训保持技术领先

数据驱动

  • 自主研发SEO分析工具
  • 实时排名监控系统
  • 竞争对手深度分析
  • 效果可视化报告

透明合作

  • 清晰的服务内容和价格
  • 定期进展汇报和沟通
  • 效果数据实时可查
  • 灵活的合同条款

我们的SEO服务理念

我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。

提交需求或反馈

Demand feedback