项目篇--微服务分布式电商

    技术2025-11-15  19

    目录

    1 系统架构2 安装环境2 创建项目2.1 创建各个微服务

    【前言】


    1 系统架构

    架构图 总的服务架构类似于上面这张图,包括

    Nginx做负载均衡gateway API网关 做流量控制、服务路由、熔断、负载均衡和鉴权等Redis集群做缓存OAuth2认证中心MySQL集群做数据持久化RabbitMQ消息队列做服务间的通信解耦ElasticSearch做全文检索OSS做对象存储服务存储视频、图像等LogStash收集业务集群的各种日志、存储到ES中,用Kibana对ES做可视化Nacos做服务注册中心:一个服务可能部署在多台服务器集群上,服务之间相互调用,就要知道彼此都在哪里Nacos做服务的配置中心:统一管理服务集群中某服务的配置信息,即在nacos中修改,集群中多台服务器上的服务均生效。服务从nacos中动态获取服务配置Sleuth+Zinkin+Metrics做服务追踪,交给Prometheus做聚合分析,给Grafana做可视化展示,Prometheus提供的alertmanager得到服务的告警信息,以邮件形式告知Docker+k8s等做持续集成

    2 安装环境

    我的环境是在之前安装好的hadoop集群的环境的基础上从hadoop05克隆出一台hadoop06虚拟机,里面安装配置好的环境包括java jdk1.8等。

    【安装虚拟机linux】 详情见:安装虚拟机

    【安装Docker】 详情见:Linux安装Docker Docker镜像加速-配置阿里云镜像仓库 常用命令:

    systemctl start docker #开启 systemctl enable docker #自启 systemctl status docker #状态 docker -v #版本 docker images #镜像 systemctl stop docker #停止

    docker教程及各种docker安装软件

    【Docker安装mysql】 详情见:Docker安装mysql docker pull mysql:5.7 #下载 创建运行mysql命令: #创建 docker run -p 3366:3306 --name mysql01 -v /opt/mysql_docker/conf:/etc/mysql/conf.d -v /opt/mysql_docker/logs:/logs -v /opt/mysql_docker/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 docker images #镜像 docker ps -a #运行 docker rm CONTAINER ID #移除 docker exec -it mysql01 bash #进入 mysql -uroot -p docker start CONTAINER ID #进入 docker update mysql01 --restart=always#自动重启

    docker下MySQL修改配置

    [client] default-character-set=utf8 [mysql] default-character-set=utf8 [mysqld] init_connect='SET collation_connection = utf8_unicode_ci' init_connect='SET NAMES utf8' character-set-server=utf8 collation-server=utf8_unicode_ci skip-character-set-client-handshake skip-name-resolve 【Navicat连接docker下的mysql】 Navicat的下载安装使用(3306端口映射到了windows的3366) 【Docker安装redis】 详情见:Docker安装redis docker pull redis:latest #下载 创建运行mysql命令: #创建 docker run -itd --name redis01 -p 6379:6379 redis docker exec -it redis01 /bin/bash #进入 redis-cli docker start CONTAINER ID #进入 docker update redis01 --restart=always#自动重启 【配置git】 下载安装、桌面右键->git bash here git config --global user.name "shaneholmes" #配置 git config --global user.email "shaneholmes@qq.com" #配置 ssh-keygen -t rsa -C "shaneholmes@qq.com" #公钥 cat ~/.ssh/id_rsa.pub 将公钥复制到码云Gitee的SSH ssh -T git@gitee.com #测试 【window安装nodejs】 npm设置使用淘宝镜像:npm config set registry http://registry.npm.taobao.org/

    2 创建项目

    首先在码云Gitee创建项目bizzmall仓库,然后从版本控制器中获取项目。这是一个总项目,各个微服务以模块形式来做。 规范:(详情参照2.1)

    模块命名规范: 组:com.shane.bizzmall 工件:bizzmall-微服务名称 名称:bizzmall-微服务名称 描述:bizzmall-XX服务 package:com.shane.bizzmall.微服务名称

    2.1 创建各个微服务

    【bizzmall-product】 商品服务 初始化springboot项目(版本2.3.1): 其他的微服务的创建类似: 【bizzmall-common】 是每一个微服务额公共依赖,bean,工具类等 在总的根目录下创建pom文件: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.shane.bizzmall</groupId> <artifactId>bizzmall</artifactId> <version>0.0.1-SNAPSHOT</version> <name>bizzmall</name> <description>bizzmall-聚合服务</description> <packaging>pom</packaging> <modules> <module>bizzmall-coupon</module> <module>bizzmall-member</module> <module>bizzmall-order</module> <module>bizzmall-product</module> <module>bizzmall-ware</module> <module>renren-fast</module> <module>renren-generator</module> <module>bizzmall-common</module> </modules> </project>

    【数据库】 链接:https://pan.baidu.com/s/1alJE31o6Trq7-yrMcm6BSQ 提取码:nagk 使用Navicat来连接wmware中linux中docker的mysql01容器,创建的数据库的字符集utf8mb4、排序规则utf8mb4_general_ci。将某pan下载的sql文件中对应的DDL在对应的数据库中执行生成表即可。

    【项目脚手架】 后端管理:$ git clone https://gitee.com/renrenio/renren-fast.git 前端页面:$ git clone https://gitee.com/renrenio/renren-fast-vue.git 克隆下来以后需要将.git文件夹删除,用vscode打开renren-fast-vue,安装依赖:npm install (相当于下载Java的maven依赖),然后运行:npm run dev

    【mybatis逆向工程】 什么叫逆向工程? 先设计好数据库,配置数据库连接,mybatis自动生成一些sql语句 如何使用 renren-generator 生成逆向工程? (几个微服务就重复几遍) 1、在\resources\application.yml文件中修改自己对应的数据库连接地址、端口号、数据库、用户名和密码 2、在\resources\generator.properties文件中修改mainPath、package、moduleName、author、email以及tablePrefix 3、启动renren-generator项目主类RenrenApplication.java,打开浏览器选择所有表点击生成代码,把生成的main文件夹拷贝对应微服务的main文件夹,添加application.yml的如下配置:

    spring: datasource: username: root password: 123456 url: jdbc:mysql://192.168.65.106:3366/bizzmall_oms driver-class-name: com.mysql.jdbc.Driver mybatis-plus: mapper-locations: classpath:/mapper/**/*.xml global-config: db-config: id-type: auto server: port: 9000 【springcloud alibaba分布式组件】 参考手册 参考手册

    由于每个微服务模块均依赖了common模块,在common的pom.xml文件添加依赖管理(以后添加的微服务依赖就不再需要些version标签了),使用2.1.0版本

    <dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.1.0.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

    nacos服务发现 添加nacos服务发现依赖

    <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId> </dependency>

    此时还没有服务发现的服务器,配置方法如下: 在 https://github.com/alibaba/nacos/releases 下载nacos-server-1.1.3,(为了方便)在windows解压后运行/bin/startup.cmd,在各个微服务的application.yml文件中新增nacos的服务发现server地址和注册到服务中的application-name:

    spring: cloud: nacos: discovery: server-addr: 127.0.0.1:8848 application: name: 微服务名称

    在各个微服务的主类上使用@EnableDiscoveryClient来开启服务注册与发现功能,将微服务项目启动 至此,已在nacos服务注册与发现中心注册了该微服务,浏览器打开 http://127.0.0.1:8848/ (账户名密码均是nacos),在服务管理/服务列表可看到注册的服务。

    feign远程调用 第一步:在被调用的服务bizzmall-coupon写上新接口(无实际含义,测试被调用而已)

    @RestController @RequestMapping("coupon/coupon") public class CouponController { @RequestMapping("/member/list") public R memberCoupons(){ CouponEntity couponEntity = new CouponEntity(); couponEntity.setCouponName("会员的优惠券"); return R.ok().put("memberCoupon",Arrays.asList(couponEntity)); } }

    第二步:在调用方bizzmall-member新写一个包feign(专门用来放远程调用的service),并新建接口CouponFeignService

    //调用bizzmall-coupon服务 @FeignClient("bizzmall-coupon") public interface CouponFeignService { //调用bizzmall-coupon服务的/coupon/coupon/member/list请求 @RequestMapping("/coupon/coupon/member/list") public R memberCoupons(); }

    第三步:在调用方bizzmall-member中写调用被调用方的接口方法

    @RestController @RequestMapping("member/member") public class MemberController { @Autowired CouponFeignService couponFeignService; @RequestMapping("/coupons") public R getMemberCoupons(){ MemberEntity memberEntity = new MemberEntity(); memberEntity.setUsername("shaneholmes"); R memberCoupons = couponFeignService.memberCoupons(); return R.ok().put("member",memberEntity).put("memberCoupons",memberCoupons.get("memberCoupons")); } } //返回拼上member和memberCoupons的map,无实际含义

    couponFeignService.memberCoupons();是远程调用过程 第四步:在主类加上注解@EnableFeignClients(basePackages = "com.shane.bizzmall.member.feign")

    第五步:启动测试(前提是已经完成nacos服务发现这一步) 发送http://localhost:8000/member/member/coupons请求,这个请求中的couponFeignService.memberCoupons();进行远程调用,它调用bizzmall-coupon服务的/coupon/coupon/member/list请求,memberCoupons 是远程调用的结果

    nacos做配置中心 参考文档 第一步:在公共项目bizzmall-common添加nacos配置依赖Nacos Config Starter

    <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId> </dependency>

    第二步:在应用的 /src/main/resources/bootstrap.properties(这个配置文件优先级比application.properties高) 配置文件中配置 Nacos Config 元数据(应用名和服务器地址)

    spring.application.name=bizzmall-coupon spring.cloud.nacos.config.server-addr=127.0.0.1:8848 spring.cloud.nacos.config.namespace=f6fc3126-0637-4c27-9159-a6ad5af0b789

    第三步:在http://localhost:8848/nacos/中创建dev和test命名空间,在dev命名空间中新建配置

    第四步:编写测试

    @RefreshScope @RestController @RequestMapping("coupon/coupon") public class CouponController { @Value("${coupon.test.name}") private String name; @RequestMapping("/test/nacos/config") public R getNacosConfig(){ return R.ok().put("nacos-config-name",name); } }

    本地application.properties文件:

    coupon.test.name=shaneholmes coupon.test.time=2020.07.15

    调用http://localhost:7000/coupon/coupon/test/nacos/config:

    可以看到,${coupon.test.name}=shane,是从nacos中取出的。(nacos覆盖本地的)

    要想动态从nacos中获取配置项的值,需要在控制器上加上注解 @RefreshScope

    可以加载多个配置:

    SpringCloudGateway 参考文档 第一步:使用springboot initialize初始化向导创建新的springboot模块,添加gateway依赖,并依赖于common模块 第二步:配置开启服务注册发现(详见上面的:nacos服务发现) 第三步:配置开启nacos配置中心(详见上面的:nacos做配置中心) 第四步:排除DataSource。由于common模块中引入了mybatis等依赖,需要在gateway模块配置数据源,不然启动报错。手动在主类BizzmallGatewayApplication中排除:@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) 第五步:测试网关的路由。在application.yml中:

    spring: cloud: nacos: discovery: server-addr: 127.0.0.1:8848 gateway: routes: - id: test_route_baidu uri: http://www.baidu.com predicates: - Query=url,baidu - id: test_route_qq uri: http://www.qq.com predicates: - Query=url,qq application: name: bizzmall-gateway server: port: 88

    在浏览器中输入:http://localhost:88/index?url=baidu会转到http://www.baidu.com/index页面。更过的使用方法详见 参考文档

    Processed: 0.018, SQL: 9