当前位置: 首页 > news >正文

戴尔电脑网站建设方案范文重庆网络建站

戴尔电脑网站建设方案范文,重庆网络建站,网站建设的销售话术,商务网站建设策划书范文1. Seata 是什么? 由于业务和技术的发展#xff0c;单体应用被拆分成微服务应用#xff0c;原来的三个模块被拆分成三个独立的应用,分别使用三个独立的数据源#xff0c;业务操作需要调用三个服务来完成。此时每个服务内部的数据一致性由本地事务来保证#xff0c; 但是全…1. Seata 是什么? 由于业务和技术的发展单体应用被拆分成微服务应用原来的三个模块被拆分成三个独立的应用,分别使用三个独立的数据源业务操作需要调用三个服务来完成。此时每个服务内部的数据一致性由本地事务来保证 但是全局的数据一致性问题没法保证。 Seata 是一款开源的分布式事务解决方案致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式为用户打造一站式的分布式解决方案。https://seata.io/zh-cn/docs/overview/what-is-seata.html seata分布式事务处理过程的一ID三组件模型 Transaction ID XID 全局唯一的事务ID三组件概念 TC (Transaction Coordinator) - 事务协调者维护全局和分支事务的状态驱动全局事务提交或回滚。TM (Transaction Manager) - 事务管理器定义全局事务的范围开始全局事务、提交或回滚全局事务。RM (Resource Manager) - 资源管理器管理分支事务处理的资源与TC交谈以注册分支事务和报告分支事务的状态并驱动分支事务提交或回滚。 处理过程 TM向TC申请开启一个全局事务全局事务创建成功并生成一个全局唯一的XIDXID在微服务调用链路的上下文中传播RM向TC注册分支事务将其纳入XID对应全局事务的管辖TM向TC发起针对XID的全局提交或回滚决议TC调度XID下管辖的全部分支事务完成提交或回滚请求。 2. seata安装 Seata分TC、TM和RM三个角色TCServer端为单独服务端部署TM和RMClient端由业务系统集成。 本例前置条件 默认nacos已经安装完成并启动并开启了持久化配置使用mysql8.0数据库 2.1. Server端安装 seata1.5.2安装 nacos2.1.1服务注册和配置中心集成 1. 下载seata 1.5.2 https://github.com/seata/seata/releases 2. 放在合适的路径下解压缩 注意路径中一定不能出现中文和空格否则会导致之后的git命令无法成功执行 3. 在数据库中创建全局事务所需要的表 全局事务会话信息由3块内容构成全局事务–分支事务–全局锁对应表global_table、branch_table、lock_table 在数据库中创建一个名叫seata的数据库 执行sql脚本创建数据表该脚本可以在seata安装包中查看或在git项目中https://github.com/seata/seata/blob/master/script/server/db/mysql.sql获取最新的sql脚本。 seata 1.5.0 新增了distributed_lock表用于 seata-server 异步任务调度并将字符集改为了utf8mb4。默认事务分组的由my_test_tx_group 修改为 default_tx_group更多升级信息可以查看官方文档https://seata.io/zh-cn/docs/ops/upgrade.html -- -------------------------------- The script used when storeMode is db -------------------------------- -- the table to store GlobalSession data CREATE TABLE IF NOT EXISTS global_table (xid VARCHAR(128) NOT NULL,transaction_id BIGINT,status TINYINT NOT NULL,application_id VARCHAR(32),transaction_service_group VARCHAR(32),transaction_name VARCHAR(128),timeout INT,begin_time BIGINT,application_data VARCHAR(2000),gmt_create DATETIME,gmt_modified DATETIME,PRIMARY KEY (xid),KEY idx_status_gmt_modified (status , gmt_modified),KEY idx_transaction_id (transaction_id) ) ENGINE InnoDBDEFAULT CHARSET utf8mb4;-- the table to store BranchSession data CREATE TABLE IF NOT EXISTS branch_table (branch_id BIGINT NOT NULL,xid VARCHAR(128) NOT NULL,transaction_id BIGINT,resource_group_id VARCHAR(32),resource_id VARCHAR(256),branch_type VARCHAR(8),status TINYINT,client_id VARCHAR(64),application_data VARCHAR(2000),gmt_create DATETIME(6),gmt_modified DATETIME(6),PRIMARY KEY (branch_id),KEY idx_xid (xid) ) ENGINE InnoDBDEFAULT CHARSET utf8mb4;-- the table to store lock data CREATE TABLE IF NOT EXISTS lock_table (row_key VARCHAR(128) NOT NULL,xid VARCHAR(128),transaction_id BIGINT,branch_id BIGINT NOT NULL,resource_id VARCHAR(256),table_name VARCHAR(32),pk VARCHAR(36),status TINYINT NOT NULL DEFAULT 0 COMMENT 0:locked ,1:rollbacking,gmt_create DATETIME,gmt_modified DATETIME,PRIMARY KEY (row_key),KEY idx_status (status),KEY idx_branch_id (branch_id),KEY idx_xid_and_branch_id (xid , branch_id) ) ENGINE InnoDBDEFAULT CHARSET utf8mb4;CREATE TABLE IF NOT EXISTS distributed_lock (lock_key CHAR(20) NOT NULL,lock_value VARCHAR(20) NOT NULL,expire BIGINT,primary key (lock_key) ) ENGINE InnoDBDEFAULT CHARSET utf8mb4;INSERT INTO distributed_lock (lock_key, lock_value, expire) VALUES (AsyncCommitting, , 0); INSERT INTO distributed_lock (lock_key, lock_value, expire) VALUES (RetryCommitting, , 0); INSERT INTO distributed_lock (lock_key, lock_value, expire) VALUES (RetryRollbacking, , 0); INSERT INTO distributed_lock (lock_key, lock_value, expire) VALUES (TxTimeoutCheck, , 0);修改seata - config下的application.yaml配置文件使用nacos作为服务注册发现中心和配置中心其他详细配置可以参照seata提供的模板application.example.yml 3.1. 在nacos中新建一个命名空间并记录下空间ID 3.2. 修改application.yml主要修改项seata 下的 config、registry、store server:port: 7091spring:application:name: seata-serverlogging:config: classpath:logback-spring.xmlfile:path: ${user.home}/logs/seataextend:logstash-appender:destination: 127.0.0.1:4560kafka-appender:bootstrap-servers: 127.0.0.1:9092topic: logback_to_logstashconsole:user:username: seatapassword: seataseata:config:# support: nacos, consul, apollo, zk, etcd3type: nacosnacos:server-addr: localhost:8848namespace: 704a579f-f1ef-45fd-818e-4e5c113ca50dgroup: SEATA_GROUPusername: nacospassword: nacos#data-id: seataServer.properties registry:# support: nacos, eureka, redis, zk, consul, etcd3, sofatype: nacosnacos:application: seata-serverserver-addr: localhost:8848group: SEATA_GROUPnamespace: 704a579f-f1ef-45fd-818e-4e5c113ca50dcluster: defaultusername: nacospassword: nacos##if use MSE Nacos with auth, mutex with username/password attribute#access-key: #secret-key: store:# support: file 、 db 、 redismode: dbdb:datasource: druiddb-type: mysqldriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/seata?rewriteBatchedStatementstrueuseUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/Shanghaiuser: rootpassword: 123456min-conn: 1max-conn: 20global-table: global_tablebranch-table: branch_tablelock-table: lock_tabledistributed-lock-table: distributed_lockquery-limit: 100max-wait: 10000server:service-port: 8091 #If not configured, the default is ${server.port} 1000max-commit-retry-timeout: -1max-rollback-retry-timeout: -1rollback-retry-timeout-unlock-enable: falseenable-check-auth: trueenable-parallel-request-handle: trueretry-dead-threshold: 130000xaer-nota-retry-timeout: 60000undo:log-save-days: 7log-delete-period: 86400000session:branch-async-queue-size: 5000 #branch async remove queue sizeenable-branch-async-remove: false #enable to asynchronous remove branchSessionsecurity:secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017tokenValidityInMilliseconds: 1800000ignore:urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login3.3. 修改config配置文件 将D:\seata\script\config-center下的config.txt复制一份到seata的目录下与bin目录同级并修改配置信息主要修改store.mode和store.db可以将不需要的配置信息删除掉以防在nacos配置中心中产生太多无用的配置项例如file和Redis的相关配置 #For details about configuration items, see https://seata.io/zh-cn/docs/user/configurations.html #Transport configuration, for client and server transport.typeTCP transport.serverNIO transport.heartbeattrue transport.enableTmClientBatchSendRequestfalse transport.enableRmClientBatchSendRequesttrue transport.enableTcServerBatchSendResponsefalse transport.rpcRmRequestTimeout30000 transport.rpcTmRequestTimeout30000 transport.rpcTcRequestTimeout30000 transport.threadFactory.bossThreadPrefixNettyBoss transport.threadFactory.workerThreadPrefixNettyServerNIOWorker transport.threadFactory.serverExecutorThreadPrefixNettyServerBizHandler transport.threadFactory.shareBossWorkerfalse transport.threadFactory.clientSelectorThreadPrefixNettyClientSelector transport.threadFactory.clientSelectorThreadSize1 transport.threadFactory.clientWorkerThreadPrefixNettyClientWorkerThread transport.threadFactory.bossThreadSize1 transport.threadFactory.workerThreadSizedefault transport.shutdown.wait3 transport.serializationseata transport.compressornone#Transaction routing rules configuration, only for the client service.vgroupMapping.default_tx_groupdefault #If you use a registry, you can ignore it service.default.grouplist127.0.0.1:8091 service.enableDegradefalse service.disableGlobalTransactionfalse#Transaction rule configuration, only for the client client.rm.asyncCommitBufferLimit10000 client.rm.lock.retryInterval10 client.rm.lock.retryTimes30 client.rm.lock.retryPolicyBranchRollbackOnConflicttrue client.rm.reportRetryCount5 client.rm.tableMetaCheckEnabletrue client.rm.tableMetaCheckerInterval60000 client.rm.sqlParserTypedruid client.rm.reportSuccessEnablefalse client.rm.sagaBranchRegisterEnablefalse client.rm.sagaJsonParserfastjson client.rm.tccActionInterceptorOrder-2147482648 client.tm.commitRetryCount5 client.tm.rollbackRetryCount5 client.tm.defaultGlobalTransactionTimeout60000 client.tm.degradeCheckfalse client.tm.degradeCheckAllowTimes10 client.tm.degradeCheckPeriod2000 client.tm.interceptorOrder-2147482648 client.undo.dataValidationtrue client.undo.logSerializationjackson client.undo.onlyCareUpdateColumnstrue server.undo.logSaveDays7 server.undo.logDeletePeriod86400000 client.undo.logTableundo_log client.undo.compress.enabletrue client.undo.compress.typezip client.undo.compress.threshold64k #For TCC transaction mode tcc.fence.logTableNametcc_fence_log tcc.fence.cleanPeriod1h#Log rule configuration, for client and server log.exceptionRate100#Transaction storage configuration, only for the server. The file, DB, and redis configuration values are optional. store.modedb store.lock.modedb store.session.modedb #Used for password encryption store.publicKey#These configurations are required if the store mode is db. If store.mode,store.lock.mode,store.session.mode are not equal to db, you can remove the configuration block. store.db.datasourcedruid store.db.dbTypemysql store.db.driverClassNamecom.mysql.cj.jdbc.Driver store.db.urljdbc:mysql://localhost:3306/seata?rewriteBatchedStatementstrueuseUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/Shanghai store.db.userroot store.db.password123456 store.db.minConn1 store.db.maxConn20 store.db.globalTableglobal_table store.db.branchTablebranch_table store.db.distributedLockTabledistributed_lock store.db.queryLimit100 store.db.lockTablelock_table store.db.maxWait10000#Transaction rule configuration, only for the server server.recovery.committingRetryPeriod1000 server.recovery.asynCommittingRetryPeriod1000 server.recovery.rollbackingRetryPeriod1000 server.recovery.timeoutRetryPeriod1000 server.maxCommitRetryTimeout-1 server.maxRollbackRetryTimeout-1 server.rollbackRetryTimeoutUnlockEnablefalse server.distributedLockExpireTime10000 server.xaerNotaRetryTimeout60000 server.session.branchAsyncQueueSize5000 server.session.enableBranchAsyncRemovefalse server.enableParallelRequestHandlefalse#Metrics configuration, only for the server metrics.enabledfalse metrics.registryTypecompact metrics.exporterListprometheus metrics.exporterPrometheusPort9898 注意需要将store.mode的三项DB改为小写dbrewriteBatchedStatementstrue,数据库链接中这一句是特别要加的可以提升执行效率 3.4. 使用git将上面修改好的seata的配置导入nacos配置中心 复制D:\seata\script\config-center\nacos下的nacos-config.sh到D:\seata\conf文件夹下 右键启用git命令输入以下命令并回车执行等待数据同步即可 sh nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -t 704a579f-f1ef-45fd-818e-4e5c113ca50d -u nacos -w nacos参数详情 -h -p 指定nacos的端口地址 -g 指定配置的分组注意是配置的分组 -t 指定命名空间ID -u -w指定nacos的用户名和密码使用nacos注册和配置认证的才需要指定。 导入成功后可以在nacos中查看到配置信息 2.2. Client端集成 基于springcloud分布式项目集成seata-Client端首先需要搭建一个简单的测试服务环境使用典型的订单系统创建分布式微服务系统共三个微服务模块 订单管理seata-order-service库存管理seata-storage-service账户管理seata-account-service 本例前置条件 1. 使用openFeign作为微服务远程调用框架 2. 使用mybatis作为持久层框架 3. 使用nacos作为服务注册中心 4. 需要注意各框架版本否则会出现版本冲突详细信息查看https://github.com/alibaba/spring-cloud-alibaba/wiki/版本说明 2.2.1. 创建父Maven项目进行依赖版本控制 主要的依赖项和使用版本 propertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingmaven.compiler.source1.8/maven.compiler.sourcemaven.compiler.target1.8/maven.compiler.targetjunit.version4.12/junit.versionlog4j.version1.2.17/log4j.versionlombok.version1.16.18/lombok.versionmysql.version8.0.23/mysql.versiondruid.version1.2.8/druid.versionmybatis.spring.boot.version1.3.2/mybatis.spring.boot.version/propertiesdependencyManagementdependencies!--springboot--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-dependencies/artifactIdversion2.3.12.RELEASE/versiontypepom/typescopeimport/scope/dependency!--springCloud--dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-dependencies/artifactIdversionHoxton.SR12/versiontypepom/typescopeimport/scope/dependency!--springCloud alibaba--dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-alibaba-dependencies/artifactIdversion2.2.9.RELEASE/versiontypepom/typescopeimport/scope/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion${mysql.version}/version/dependencydependencygroupIdcom.alibaba/groupIdartifactIddruid-spring-boot-starter/artifactIdversion${druid.version}/version/dependencydependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion${mybatis.spring.boot.version}/version/dependency!--junit--dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion${junit.version}/version/dependency!--log4j--dependencygroupIdlog4j/groupIdartifactIdlog4j/artifactIdversion${log4j.version}/version/dependency/dependencies/dependencyManagement2.2.2. 创建库存管理微服务seata-storage-service 1. 添加pom依赖在父项目下新建module seata-storage-service2002并添加依赖 artifactIdseata-storage-service2002/artifactIddependencies!--nacos--dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId/dependency!--seata--dependencygroupIdio.seata/groupIdartifactIdseata-spring-boot-starter/artifactIdversion1.5.2/version/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-seata/artifactIdversion2021.1/versionexclusionsexclusiongroupIdio.seata/groupIdartifactIdseata-spring-boot-starter/artifactId/exclusion/exclusions/dependency!--web--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-actuator/artifactId/dependency!--mysql connector--dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactId/dependency!--mysql druid--dependencygroupIdcom.alibaba/groupIdartifactIddruid-spring-boot-starter/artifactId/dependency!--mybatis--dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependency/dependencies2. 修改application.yaml配置以下为全部配置信息 需要先创建一个名叫seata_storage的数据库以便数据库链接的配置 server:port: 2002spring:application:name: seata-storage-servicecloud:nacos:discovery:server-addr: localhost:8848datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/seata_storage?useUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/Shanghaiusername: rootpassword: 123456mybatis:mapper-locations: classpath:mapper/*.xml# seata 配置 seata:# seata配置中心tx-service-group: default_tx_groupconfig:type: nacosnacos:namespace: 704a579f-f1ef-45fd-818e-4e5c113ca50d# nacos配置中心地址server-addr: localhost:8848# 分组group: SEATA_GROUP# nacos的账号和密码userName: nacospassword: nacos# seata的注册中心registry:type: nacosnacos:application: seata-serverserver-addr: localhost:8848namespace: 704a579f-f1ef-45fd-818e-4e5c113ca50duserName: nacospassword: nacosservice:vgroup-mapping:default_tx_group: default3. 编写业务代码 整体包结构 domain包 CommonResult package com.atguigu.alibaba.seata.domain;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月17日*/ Data AllArgsConstructor NoArgsConstructor public class CommonResultT {private Integer code;private String message;private T data;public CommonResult(Integer code, String message){this(code,message,null);} }Storage package com.atguigu.alibaba.seata.domain;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月18日*/ Data NoArgsConstructor AllArgsConstructor public class Storage {private Long id; //主键private Long productId; //产品IDprivate Integer total; //库存总量private Integer used; //已用库存数量private Integer residue; //剩余库存数量 }数据库建表sql在seata_storage下创建业务表 CREATE TABLE t_storage ( id BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, product_id BIGINT(11) DEFAULT NULL COMMENT 产品id, total INT(11) DEFAULT NULL COMMENT 总库存, used INT(11) DEFAULT NULL COMMENT 已用库存, residue INT(11) DEFAULT NULL COMMENT 剩余库存 ) ENGINEINNODB AUTO_INCREMENT1 DEFAULT CHARSETutf8;INSERT INTO seata_storage.t_storage(id, product_id, total, used, residue) VALUES (1, 1, 100, 0,100);SELECT * FROM t_storage;dao包 StorageDao package com.atguigu.alibaba.seata.dao;import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月18日*/ Mapper public interface StorageDao {public void decrease(Param(productId) Long productId, Param(count) Integer count); }在resources下创建一个名叫mapper的文件夹用来放mybatis的xml映射文件 ?xml version1.0 encodingUTF-8 ? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd !--Dao的全路径-- mapper namespacecom.atguigu.alibaba.seata.dao.StorageDao!--对应entity的全路径--resultMap idBaseResultMap typecom.atguigu.alibaba.seata.domain.Storageid columnid propertyid jdbcTypeBIGINT/result columnproduct_id propertyproductId jdbcTypeBIGINT/result columntotal propertytotal jdbcTypeINTEGER/result columnused propertyused jdbcTypeINTEGER/result columnresidue propertyresidue jdbcTypeINTEGER//resultMapupdate iddecreaseupdatet_storagesetused used #{count}, residue residue - #{count}whereproduct_id #{productId}/update /mapperservice包 StorageService package com.atguigu.alibaba.seata.service;import org.springframework.web.bind.annotation.RequestParam;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月18日*/ public interface StorageService {public void decrease(RequestParam(productId) Long productId,RequestParam(count) Integer count); }service.impl包 StorageServiceImpl package com.atguigu.alibaba.seata.service.impl;import com.atguigu.alibaba.seata.dao.StorageDao; import com.atguigu.alibaba.seata.service.StorageService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service;import javax.annotation.Resource;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月18日*/ Service public class StorageServiceImpl implements StorageService {private static final Logger LOGGER LoggerFactory.getLogger(StorageServiceImpl.class);Resourceprivate StorageDao storageDao;Overridepublic void decrease(Long productId, Integer count) {LOGGER.info(-------storage-service中扣减库存开始);storageDao.decrease(productId,count);LOGGER.info(-------storage-service中扣减库存结束);} }controller包 StorageController package com.atguigu.alibaba.seata.controller;import com.atguigu.alibaba.seata.domain.CommonResult; import com.atguigu.alibaba.seata.service.StorageService; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月18日*/ RestController Slf4j public class StorageController {Resourceprivate StorageService storageService;RequestMapping(/storage/decrease)public CommonResult decrease(RequestParam(productId) Long productId,RequestParam(count) Integer count){storageService.decrease(productId, count);return new CommonResult(200,扣减库存成功);} }config包配置mybatis的包扫描 MyBatisConfig package com.atguigu.alibaba.seata.config;import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Configuration;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月18日*/ Configuration MapperScan({com.atguigu.alibaba.seata.dao}) public class MyBatisConfig {}主程序入口 package com.atguigu.alibaba.seata;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月18日*/ EnableDiscoveryClient SpringBootApplication public class StorageMain {public static void main(String[] args) {SpringApplication.run(StorageMain.class,args);} }2.2.3. 创建账户管理微服务seata-account-service 1. 添加pom依赖在父项目下新建module seata-account-service2003并添加依赖 artifactIdseata-account-service2003/artifactIddependencies!--nacos--dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId/dependency!--seata--dependencygroupIdio.seata/groupIdartifactIdseata-spring-boot-starter/artifactIdversion1.5.2/version/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-seata/artifactIdversion2021.1/versionexclusionsexclusiongroupIdio.seata/groupIdartifactIdseata-spring-boot-starter/artifactId/exclusion/exclusions/dependency!--web--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-actuator/artifactId/dependency!--mysql connector--dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactId/dependency!--mysql druid--dependencygroupIdcom.alibaba/groupIdartifactIddruid-spring-boot-starter/artifactId/dependency!--mybatis--dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependency/dependencies2. 修改application.yaml配置以下为全部配置信息 需要先创建一个名叫seata_account的数据库以便数据库链接的配置 server:port: 2003spring:application:name: seata-account-servicecloud:nacos:discovery:server-addr: localhost:8848datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/seata_account?useUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/Shanghaiusername: rootpassword: 123456mybatis:mapper-locations: classpath:mapper/*.xml# seata 配置 seata:# seata配置中心tx-service-group: default_tx_groupconfig:type: nacosnacos:namespace: 704a579f-f1ef-45fd-818e-4e5c113ca50d# nacos配置中心地址server-addr: localhost:8848# 分组group: SEATA_GROUP# nacos的账号和密码userName: nacospassword: nacos# seata的注册中心registry:type: nacosnacos:application: seata-serverserver-addr: localhost:8848namespace: 704a579f-f1ef-45fd-818e-4e5c113ca50duserName: nacospassword: nacosservice:vgroup-mapping:default_tx_group: default3. 编写业务代码 整体包结构 domain包 CommonResult package com.atguigu.alibaba.seata.domain;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月17日*/ Data AllArgsConstructor NoArgsConstructor public class CommonResultT {private Integer code;private String message;private T data;public CommonResult(Integer code, String message){this(code,message,null);} }Account package com.atguigu.alibaba.seata.domain;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.math.BigDecimal;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月18日*/ Data AllArgsConstructor NoArgsConstructor public class Account {private Long id; //主键private Long userId; //用户IDprivate BigDecimal total; //账户总额private BigDecimal used; //已使用额度private BigDecimal residue; //剩余额度 }数据库建表sql在seata_account下创建业务表 CREATE TABLE t_account(id BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT id,user_id BIGINT(11) DEFAULT NULL COMMENT 用户id,total DECIMAL(10,0) DEFAULT NULL COMMENT 总额度,used DECIMAL(10,0) DEFAULT NULL COMMENT 已用余额,residue DECIMAL(10,0) DEFAULT 0 COMMENT 剩余可用额度 ) ENGINEINNODB AUTO_INCREMENT1 DEFAULT CHARSETutf8;INSERT INTO seata_account.t_account(id, user_id, total, used, residue) VALUES (1, 1, 1000, 0, 1000);SELECT * FROM t_account;dao包 AccountDao package com.atguigu.alibaba.seata.dao;import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param;import java.math.BigDecimal;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月18日*/ Mapper public interface AccountDao {public void decrease(Param(userId) Long userId,Param(money) BigDecimal money); }在resources下创建一个名叫mapper的文件夹用来放mybatis的xml映射文件 ?xml version1.0 encodingUTF-8 ? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.atguigu.alibaba.seata.dao.AccountDaoresultMap idBaseResultMap typecom.atguigu.alibaba.seata.domain.Accountid propertyid columnid jdbcTypeBIGINT/result propertyuserId columnuser_id jdbcTypeBIGINT/result propertytotal columntotal jdbcTypeDECIMAL/result propertyused columnused jdbcTypeDECIMAL/result propertyresidue columnresidue jdbcTypeDECIMAL//resultMapupdate iddecreaseupdatet_accountsetresidue residue - #{money}, used used #{money}whereuser_id #{userId}/update /mapperservice包 AccountService package com.atguigu.alibaba.seata.service;import org.springframework.web.bind.annotation.RequestParam;import java.math.BigDecimal;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月18日*/ public interface AccountService {public void decrease (RequestParam(userId) Long userId,RequestParam(money) BigDecimal money); }service.impl包 AccountServiceImpl package com.atguigu.alibaba.seata.service.impl;import com.atguigu.alibaba.seata.dao.AccountDao; import com.atguigu.alibaba.seata.service.AccountService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service;import javax.annotation.Resource; import java.math.BigDecimal;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月18日*/ Service public class AccountServiceImpl implements AccountService {private static final Logger LOGGER LoggerFactory.getLogger(AccountServiceImpl.class);Resourceprivate AccountDao accountDao;Overridepublic void decrease(Long userId, BigDecimal money) {LOGGER.info(-------Account-service中扣减金额开始);accountDao.decrease(userId, money);LOGGER.info(-------Account-service中扣减金额结束);} }controller包 package com.atguigu.alibaba.seata.controller;import com.atguigu.alibaba.seata.domain.CommonResult; import com.atguigu.alibaba.seata.service.AccountService; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource; import java.math.BigDecimal;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月18日*/ RestController public class AccountController {Resourceprivate AccountService accountService;RequestMapping(/account/decrease)public CommonResult decrease(RequestParam(userId) Long userId,RequestParam(money) BigDecimal money){accountService.decrease(userId, money);return new CommonResult(200,扣减账户余额成功);} }config包 MyBatisConfig package com.atguigu.alibaba.seata.config;import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Configuration;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月18日*/ Configuration MapperScan({com.atguigu.alibaba.seata.dao}) public class MyBatisConfig {}主程序入口 package com.atguigu.alibaba.seata;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月18日*/ EnableDiscoveryClient SpringBootApplication public class AccountMain {public static void main(String[] args) {SpringApplication.run(AccountMain.class,args);} }2.2.4. 创建订单管理微服务seata-order-service 1. 添加pom依赖在父项目下新建module seata-order-service2001并添加依赖 artifactIdseata-order-service2001/artifactIddependencies!--nacos--dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId/dependency!--seata 官方文档推荐依赖添加方式--dependencygroupIdio.seata/groupIdartifactIdseata-spring-boot-starter/artifactIdversion1.5.2/version/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-seata/artifactIdversion2021.1/versionexclusionsexclusiongroupIdio.seata/groupIdartifactIdseata-spring-boot-starter/artifactId/exclusion/exclusions/dependency!--openfeign--dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactIdversion2.2.0.RELEASE/version/dependency!--web-actuator--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-actuator/artifactId/dependency!--mysql-druid--dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactId/dependencydependencygroupIdcom.alibaba/groupIdartifactIddruid-spring-boot-starter/artifactIdversion1.1.10/version/dependency!--mybatis--dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependency/dependencies2. 修改application.yaml配置以下为全部配置信息 需要先创建一个名叫seata_order的数据库以便数据库链接的配置 server:port: 2001spring:application:name: seata-order-servicecloud:nacos:discovery:server-addr: localhost:8848datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/seata_order?useUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/Shanghaiusername: rootpassword: 123456mybatis:mapper-locations: classpath:mapper/*.xml# seata 配置 seata:# seata配置中心tx-service-group: default_tx_groupconfig:type: nacosnacos:namespace: 704a579f-f1ef-45fd-818e-4e5c113ca50d# nacos配置中心地址server-addr: localhost:8848# 分组group: SEATA_GROUP# nacos的账号和密码userName: nacospassword: nacos# seata的注册中心registry:type: nacosnacos:application: seata-serverserver-addr: localhost:8848namespace: 704a579f-f1ef-45fd-818e-4e5c113ca50duserName: nacospassword: nacosservice:vgroup-mapping:default_tx_group: default3. 编写业务代码 整体包结构 domain包 CommonResult package com.atguigu.alibaba.seata.domain;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月17日*/ Data AllArgsConstructor NoArgsConstructor public class CommonResultT {private Integer code;private String message;private T data;public CommonResult(Integer code, String message){this(code,message,null);} }Order也就是entity和数据库字段对应 package com.atguigu.alibaba.seata.domain;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.math.BigDecimal;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月17日*/ Data AllArgsConstructor NoArgsConstructor public class Order {private Long id;private Long userId;private Long productId;private Integer count;private BigDecimal money;private Integer status; //订单状态0创建中1已完结 }数据库建表sql在数据库中新建一个名叫seata-order的数据库并创建业务表 CREATE TABLE t_order (id BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,user_id BIGINT(11) DEFAULT NULL COMMENT 用户id,product_id BIGINT(11) DEFAULT NULL COMMENT 产品id,count INT(11) DEFAULT NULL COMMENT 数量,money DECIMAL(11,0) DEFAULT NULL COMMENT 金额,status INT(1) DEFAULT NULL COMMENT 订单状态: 0:创建中; 1:已完结 ) ENGINEINNODB AUTO_INCREMENT1 DEFAULT CHARSETutf8;SELECT * FROM t_order;dao包 OrderDao package com.atguigu.alibaba.seata.dao;import com.atguigu.alibaba.seata.domain.Order; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月17日*/ Mapper public interface OrderDao {//1 新建订单public void create(Order order);//2 修改订单状态从零改为1public void update(Param(userId) Long userId, Param(status) Integer status); }在resources下创建一个名叫mapper的文件夹用来放mybatis的xml映射文件 ?xml version1.0 encodingUTF-8 ? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd !--Dao的全路径-- mapper namespacecom.atguigu.alibaba.seata.dao.OrderDao!--对应entity的全路径--resultMap idBaseResultMap typecom.atguigu.alibaba.seata.domain.Orderid columnid propertyid jdbcTypeBIGINT/result columnuser_id propertyuserId jdbcTypeBIGINT/result columnproduct_id propertyproductId jdbcTypeBIGINT/result columncount propertycount jdbcTypeINTEGER/result columnmoney propertymoney jdbcTypeDECIMAL/result columnstatus propertystatus jdbcTypeINTEGER//resultMapinsert idcreateinsert into t_order (id,user_id,product_id,count,money,status)values (null,#{userId},#{productId},#{count},#{money},0);/insertupdate idupdateupdate t_order set status 1where user_id#{userId} and status #{status};/update /mapperservice包因为订单服务需要调用库存和账户服务所以需要使用openFeign进行远程调用服务接口并且需要先行将这两个服务的接口创建好 StorageService package com.atguigu.alibaba.seata.service;import com.atguigu.alibaba.seata.domain.CommonResult; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月17日*/ Service(storageService) FeignClient(value seata-storage-service) public interface StorageService {PostMapping(value /storage/decrease)CommonResult decrease(RequestParam(productId) Long productId, RequestParam(count) Integer count); }AccountService package com.atguigu.alibaba.seata.service;import com.atguigu.alibaba.seata.domain.CommonResult; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam;import java.math.BigDecimal;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月17日*/ Service(accountService) FeignClient(value seata-account-service) public interface AccountService {PostMapping(value /account/decrease)CommonResult decrease(RequestParam(userId) Long userId,RequestParam(money) BigDecimal money); }OrderService package com.atguigu.alibaba.seata.service;import com.atguigu.alibaba.seata.domain.Order;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月17日*/ public interface OrderService {void create(Order order); }service.impl包 OrderServiceImpl package com.atguigu.alibaba.seata.service.impl;import com.atguigu.alibaba.seata.dao.OrderDao; import com.atguigu.alibaba.seata.domain.Order; import com.atguigu.alibaba.seata.service.AccountService; import com.atguigu.alibaba.seata.service.OrderService; import com.atguigu.alibaba.seata.service.StorageService; import io.seata.spring.annotation.GlobalTransactional; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service;import javax.annotation.Resource;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月17日*/ Service Slf4j public class OrderServiceImpl implements OrderService {Resourceprivate OrderDao orderDao;Resourceprivate StorageService storageService;Resourceprivate AccountService accountService;OverrideGlobalTransactionalpublic void create(Order order) {log.info(-----开始新建订单);//1 新建订单orderDao.create(order);//2 扣减库存log.info(-----订单微服务开始调用库存做扣减Count);storageService.decrease(order.getProductId(),order.getCount());log.info(-----订单微服务开始调用库存做扣减end);//3 扣减账户log.info(-----订单微服务开始调用账户做扣减Money);accountService.decrease(order.getUserId(),order.getMoney());log.info(-----订单微服务开始调用账户做扣减end);//4 修改订单状态从零到1,1代表已经完成log.info(-----修改订单状态开始);orderDao.update(order.getUserId(),0);log.info(-----修改订单状态结束);} }controller包 OrderSeataController package com.atguigu.alibaba.seata.controller;import com.atguigu.alibaba.seata.domain.CommonResult; import com.atguigu.alibaba.seata.domain.Order; import com.atguigu.alibaba.seata.service.OrderService; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月17日*/ RestController public class OrderSeataController {Resourceprivate OrderService orderService;GetMapping(/order/create)public CommonResult create(Order order){orderService.create(order);return new CommonResult(200,订单创建成功);} }config包 package com.atguigu.alibaba.seata.config;import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Configuration;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月17日*/ Configuration MapperScan({com.atguigu.alibaba.seata.dao}) public class MyBatisConfig {}主程序入口 package com.atguigu.alibaba.seata;import io.seata.spring.annotation.datasource.EnableAutoDataSourceProxy; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients;/*** author 强浩* version 1.0.0* Copyright(c) YTANG All Rights Reserved* className* project 管理系统* date 2022年10月17日*/ SpringBootApplication EnableDiscoveryClient EnableFeignClients EnableAutoDataSourceProxy public class OrderMain {public static void main(String[] args) {SpringApplication.run(OrderMain.class,args);} }2.2.5. 集成Seata - Client 1. 添加seata依赖编写业务代码时已经添加完毕 2. 在所有需要进行全局事务管理的业务数据库下新建undo_log表、配置参数(仅AT模式) -- the table to store seata xid data -- 0.7.0 add context -- you must to init this sql for you business databese. the seata server not need it. -- 此脚本必须初始化在你当前的业务数据库中用于AT 模式XID记录。与server端无关注业务数据库 -- 注意此处0.3.0 增加唯一索引 ux_undo_log drop table undo_log; CREATE TABLE undo_log (id bigint(20) NOT NULL AUTO_INCREMENT,branch_id bigint(20) NOT NULL,xid varchar(100) NOT NULL,context varchar(128) NOT NULL,rollback_info longblob NOT NULL,log_status int(11) NOT NULL,log_created datetime NOT NULL,log_modified datetime NOT NULL,ext varchar(100) DEFAULT NULL,PRIMARY KEY (id),UNIQUE KEY ux_undo_log (xid,branch_id) ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8;3. 数据源代理不支持自动和手动配置并存我这里使用的是seata-starter默认开启了自动数据源代理无需修改 4. 初始化GlobalTransactionScanner:自动引入seata-spring-boot-starter、spring-cloud-starter-alibaba-seata等jar无需修改 5. 实现xid跨服务传递自动 springCloud用户可以引入spring-cloud-starter-alibaba-seata内部已经实现xid传递无需修改 官方部署指南https://seata.io/zh-cn/docs/ops/deploy-guide-beginner.html 2.2.6. 业务使用 注解拦截全局事务 在需要进行全局事务管理的入口接口上标注 GlobalTransactional例 Service Slf4j public class OrderServiceImpl implements OrderService {Resourceprivate OrderDao orderDao;Resourceprivate StorageService storageService;Resourceprivate AccountService accountService;OverrideGlobalTransactionalpublic void create(Order order) {log.info(-----开始新建订单);//1 新建订单orderDao.create(order);//2 扣减库存log.info(-----订单微服务开始调用库存做扣减Count);storageService.decrease(order.getProductId(),order.getCount());log.info(-----订单微服务开始调用库存做扣减end);//3 扣减账户log.info(-----订单微服务开始调用账户做扣减Money);accountService.decrease(order.getUserId(),order.getMoney());log.info(-----订单微服务开始调用账户做扣减end);//4 修改订单状态从零到1,1代表已经完成log.info(-----修改订单状态开始);orderDao.update(order.getUserId(),0);log.info(-----修改订单状态结束);} }2.2.7. 测试 1. 启动seata-server双击bin下的seata-server.bat 2. 启动三个微服务 发送请求这时应该可以正常创建数据并扣减数据 http://localhost:2001/order/create?userId1productId1count10money100 3. 先不添加GlobalTransactional注解 在关闭account账户服务的情况下发送请求这时数据库应该创建了订单信息和扣减了库存但账户没有扣减出现了数据的不一致 http://localhost:2001/order/create?userId1productId1count10money100 4. 添加GlobalTransactional注解在关闭account账户服务的情况下 发送请求这时数据库应该不会创建任何数据加粗样式
http://www.dnsts.com.cn/news/146014.html

相关文章:

  • 在哪了做网站app开发用什么工具
  • 怎么做同城网站重庆最近新闻大事件
  • 注册网站免费注册邮箱苏州三石网络科技有限公司
  • 临淄网站推广wordpress 4.9 zh cn
  • 视觉设计网站做网站架构需要什么步骤
  • 专注微商推广的网站泉州彩票网站建设
  • 长春建设局网站安卓app上架费用
  • 长沙网站推广平台广州统一企业官网建设
  • 程序员帮忙做放贷网站新网备案成功了怎么做网站
  • 做网站营业范围企业为什么要自助建站
  • 贵州省城乡住房和建设厅网站青白江区建设局网站
  • 中山网站建设中山犀牛云做网站费用
  • 商城网站建设推荐域名注册网站 不认证
  • 深圳注册公司需要哪些材料和流程资源seo网站优化排名
  • 网页制作与网站建设教程视频全网营销整合营销
  • 莱芜区网站网上服装设计培训班
  • 带引导页的网站404做的好的网站
  • 3d渲染网站建设wordpress代码下载
  • 民治营销型网站制作做游戏直播那个网站
  • 做IT的需要别人打开网站吗企业名录查询
  • 门户网站运营网站右下角代码
  • 襄阳地区网站做的好的网站 布局
  • 国内外基于vue框架的网站建设现状古香古色网站模板
  • 企业在网站建设上的不足做网站的电话号码
  • 网站建设金手指排名霸屏做销售找客户的网站
  • 甘肃建设厅执业资格注册中心网站狗贩子怎么做网站卖狗
  • 山东网站建设价格全球设计网优秀板式作品
  • 防火墙 网站做端口映射四大门户网站
  • 青岛网站建站公司网址转短链接
  • 记事本做网站如何排版南京做网站建设的公司排名