【谷粒商城】

一、项目介绍

1.微服务架构图

【谷粒商城】_第1张图片

2.微服务划分图

【谷粒商城】_第2张图片

二、环境搭建

1.虚拟机搭建环境

这里我买了华为云,没用虚拟机
华为云配置
【谷粒商城】_第3张图片

2.Linux 安装docker

docker文档:https://docs.docker.com/engine/install/centos/

# 1. 卸载之前的docker
 sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
                  
# 2.安装 Docker-CE
sudo yum install -y yum-utils \
	device-mapper-persistent-data \
	lvm2
#设置 docker repo 的 yum 位置
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo

#安装 docker,以及 docker-cli
sudo yum install docker-ce docker-ce-cli containerd.io

# 3.启动docker
docker systemctl start docker
# 4. 使用docker version查看是否按照成功
docker version

#5.配置 docker镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://82m9ar63.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart dock


3.docker安装配置mysql

1.安装mysql

docker pull mysql5.7

2.创建实例并启动

# 运行容器
sudo docker run -p 3312:3306 --name mysql \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
# 参数说明 -p 3312:3306 将容器的3306端口映射到主机的3312端口
# -v 宿主机文件目录:容器内目录  将容器内文件挂载到宿主机上
# -e MYSQL_ROOT_PASSWORD=root 设置mysql密码为root
# -d 后台启动
# --name 给启动容器起名字

# 使用docker ps 查看启动的容器

3.修改mysql配置文件

# 进入配置文件挂载的目录下
cd /mydata/mysql/conf

# 编辑配置文件my.cnf
vim my.cnf

# 新增配置文件内容
[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

# 修改配置文件之后,重启容器
docker restart mysql

4.通过容器的 mysql 命令行工具连接

docker exec -it mysql mysql -uroot -proot

5.设置root远程访问

grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;
flush privileges;

6.进入容器文件系统

docker exec -it mysql /bin/bash

4.docker安装配置redis

如果直接挂载的话docker会以为挂载的是一个目录,所以我们先创建一个文件然后再挂载,在虚拟机中

# 1、创建配置文件
mkdir -p /mydata/redis/conf
touch /mydata/redis/conf/redis.conf

# 2、下载镜像
docker pull redis

# 3、启动容器
# 云服务器一定要修改端口或配置密码,否则会被拉去挖矿
docker run -p 6379:6379 --name redis \
-v /mydata/redis/data:/data  \
-v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf

# 4、直接进入redis客户端
docker exec -it redis redis-cli

修改配置文件,最新的redis默认持久化,我就没有改配置文件

vim /mydata/redis/conf/redis.conf

# 插入下面内容
appendonly yes    # 支持持久化
requirepass xxxxxx # 配置redis密码

# 保存
docker restart redis

# 进入redis客户端
docker exec -it redis redis-cli
auth xxxxxx

redis配置文件详解redis配置文件

redis可视化工具安装

连接:https://www.jb51.net/softs/669908.html#downintro2

下载完毕解压,运行文件夹中 redisdestop_v2020.5.0.exe 傻瓜式安装

连接到远程redis,输入账号密码即可

5.配置开发环境

下载maven并配置
IDEA安装插件lombok,mybatisX。IDEA设置里配置好maven

6.安装vscode

下载地址https://code.visualstudio.com/Download

vscode用于前端管理系统,在vsCode里安装插件

  • Auto Close Tag
  • Auto Rename Tag
  • Chinese
  • ESlint
  • HTML CSS Support
  • HTML Snippets
  • JavaScript ES6
  • Live Server
  • open in brower
  • Vetur

7.配置git

git、github使用详细笔记,见大佬https://blog.csdn.net/weixin_44190665/article/details/118024018

8.IDEA配置码云

码云上新建项目
IDEA上新建项目,选择从VC上创建,选择刚刚新建的仓库

9.初始化项目结构

1.建立子模块
在工程目录下新建Module,选择Spring Boot Initilizr新建,加上Spring web和openFeign,创建5个子模块。注意SpringBoot的版本在创建时无法选择,创建后在pom.xml中更改版本号为2.1.8.RELEASE

2.创建父模块
在工程目录下新建pom.xml文件,删掉多余属性,刷新项目

3.过滤上传git的垃圾文件
点开父工程的.gitignore文件,添加如下内容

**/mvnw
**/mvnw.cmd

**/.mvn
**/target/

.idea

**/.gitignore

4.向码云提交项目
填写提交信息、点击commit and push
5.查看码云,是否只有pom文件和源码

10.初始化数据库

创建数据库,运行sql文件,得到5个子模块的数据库

三、快速开发

1.使用人人开源框架搭建后台管理系统

1、码云上搜索人人开源,找到renren-fast(后台管理系统),renren-fast-vue(前端), 克隆到本地
【谷粒商城】_第4张图片
2.删除renren-fast中的.git文件,把其余文件拷贝到项目中

3.修改父工程的pom.xml,把renren-fast 加入父工程
【谷粒商城】_第5张图片
4.修改renren-fast中的pom文件
pom文件出现报错,需要修改

报错原因:子模块的parent写的并不是子模块的上一级,而是继承了springboot
解决方法:在parent标签之中修改版本号

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.8.RELEASE</version>
		<relativePath ></relativePath>
	</parent>

报错原因:plugin部分报错
解决办法:引入依赖或显示声明版本

<!-- https://mvnrepository.com/artifact/com.spotify/docker-maven-plugin -->
<dependency>
   <groupId>com.spotify</groupId>
   <artifactId>docker-maven-plugin</artifactId>
   <version>0.4.14</version>
</dependency>

<dependency>
	<groupId>org.codehaus.mojo</groupId>
	<artifactId>wagon-maven-plugin</artifactId>
	<version>1.0</version>
</dependency>

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-surefire-plugin</artifactId>
	<version>2.22.2</version>
	<configuration>
		<skipTests>true</skipTests>
	</configuration>
</plugin>

5.创建后台管理系统的数据库gulimall_admin
sql文件在renren-fast/db/ 目录下,找到其中的mysql.sql 复制,运行

6.修改renren-fast的配置文件、配置数据库
查看application.yml,发现当前环境为dev
【谷粒商城】_第6张图片
配置url中的ip地址,访问的用户名和密码
【谷粒商城】_第7张图片
7.启动renren-fast项目
报错
【谷粒商城】_第8张图片
【谷粒商城】_第9张图片

报错原因:Spring Boot版本升级后lombok版本相关api有所改动
解决方式:修改.xml文件中lombok版本,修改CorsConfig.java文件
【谷粒商城】_第10张图片
【谷粒商城】_第11张图片
解决后重新启动
在这里插入图片描述
运行成功

8.前端联调
首先安装nodehttps://nodejs.org/dist/v10.16.3/
安装后检查node.js

node -v

配置淘宝镜像

npm config set registry http://registry.npm.taobao.org/

vue项目用vscode打开,运行npm install命令,加载项目依赖,有点慢,有些依赖出错,没管

执行命令npm run dev运行项目,出现下图,运行成功
【谷粒商城】_第12张图片
前后端联调,后台系统也运行起来
用户admin,密码admin,登录系统,看到的内容其实都是后台数据库查询出来的
【谷粒商城】_第13张图片

2.人人开源逆向工程搭建

1.克隆renren-generator
【谷粒商城】_第14张图片
2.删除其中的.git文件,复制到工程中,添加到父工程

3.pom.xml中添加

4.修改renren-generator的配置文件application.yml,配置自己的数据源
先生成gulimall-pms

5.修改生成器信息 generator.properties

6.修改src/main/resources/template/Controller.java.vm
删除导入shiro的语句,注释掉该位置,此处的注释是shiro提供的,我们以后要用spring security
7.运行generator项目,访问localhost:80,选中所有表,生成代码
8.解压生成的代码,把mian文件夹复制到gulimall-product/src下
\resources\src\views\modules\product (前端文件,用不到,删掉)
9.解决生成的代码报错
新建gulimall-common模块,用来引入每一个微服务公共的依赖、bean、工具类等
【谷粒商城】_第15张图片
gulimall-common中的pom文件

<dependencies>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.4.14</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
    </dependencies>

先解决product中的问题,product的pom文件加上common的依赖

<dependency>
            <groupId>com.atguigu.gulimall</groupId>
            <artifactId>gulimall-common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
</dependency>

由此解决dao、entity的报错

接下来解决service报错
在gulimall-common中按照要求创建包,引入PageUtils、Query、R、exception(在renren-fast里面复制)
复制xss下面的HTMLFilter、SQLFilter
【谷粒商城】_第16张图片

依次解决所有报错

3.测试基本的CRUD功能

1.在gulimall-common中导入mybatis-plus依赖(已完成)

2.配置数据源,以gulimall-product为例

  • 在guli-common模块中引入mysql的依赖
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.17</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
  • 在product模块中配置数据源、端口等相关信息
server:
  port: 10000

spring:
  datasource:
    username: root
    password: xxxxxx
    url: jdbc:mysql://55.144.13.121:1234/gulimall_pms?userUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.jdbc.Driver

mybatis-plus:
  mapper-locations: classpath*:/mapper/**/*.xml
  global-config:
    db-config:
      id-type: auto   # 主键自增

  • 在测试类中进行测试

这里注意检查springboot和springCloud的版本兼容问题,如果不兼容在pom文件中更改cloud版本
Test类等依赖也要加

@RunWith(SpringRunner.class)
@SpringBootTest
public class GulimallProductApplicationTests {

    @Autowired
    BrandService brandService;

    @Test
    public void contextLoads(){
        BrandEntity brandEntity = new BrandEntity();
        brandEntity.setName("华为");
        brandService.save(brandEntity);
        System.out.println("保存成功");
    }

}

查看数据库,新增数据成功

同理自测删除、修改、查询

4.快速生成所有CRUD代码

1.先配置微服务端口,按顺序coupon/member/order/product/ware分别为7000/8000/9000/10000/11000

2.修改生成器代码配置
【谷粒商城】_第17张图片
【谷粒商城】_第18张图片
3.生成coupon的代码,复制到工程中,并在gulimall-coupon工程中引入gulimall-common依赖

4.修改gulimall-coupon的配置文件
从product复制过去,只需要修改数据库名字和端口

5.启动后访问http://localhost:7000/coupon/coupon/list测试
在这里插入图片描述
测试成功

6.按照以上方法分别生成gulimall-member/gulimall-order/gulimall-ware的代码

四、分布式组件

1.nacos用作注册中心

1.nacos下载安装

  • 下载地址:https://github.com/alibaba/nacos/releases
  • 解压安装包,直接运行bin目录下的startup.cmd
  • 命令运行成功后直接访问http://localhost:8848/nacos,默认账号密码都是nacos

2.使用nacos

  • 配置文件中加上注册中心的地址
  • 配置文件中加上本服务的名字
server:
  port: 7000

spring:
  datasource:
    username: root
    password: xxxxxx
    url: jdbc:mysql://64.114.116.33:1234/gulimall_sms?userUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: gulimall-coupon
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
            
mybatis-plus:
  mapper-locations: classpath*:/mapper/**/*.xml
  global-config:
    db-config:
      id-type: auto   # 主键自增
  • common模块中导入依赖
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

  • 在主启动类上使用 @EnableDiscoveryClient 注解开启服务注册与发现功能
@EnableDiscoveryClient
@SpringBootApplication
public class GulimallCouponApplication {
    public static void main(String[] args) {
        SpringApplication.run(GulimallCouponApplication.class, args);
    }
}

3.启动gulimall-coupon, 查看服务注册中心
【谷粒商城】_第19张图片
4.按照以上步骤依次给member/order/product/ware配置

2.openfegin远程调用

声明式远程调用

feign是一个声明式的HTTP客户端,他的目的就是让远程调用更加简单。给远程服务发的是HTTP请求

会员服务想要远程调用优惠券服务,只需要给会员服务里引入openfeign依赖,他就有了远程调用其他服务的能力

1.common模块引入openfeign依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2. 演示member服务调用coupon服务

  • 在gulimall-coupon中的CouponController中添加测试方法
    @RequestMapping("/member/list")
    public R membercoupons(){    //全系统的所有返回都返回R
        // 模拟去数据库查用户对于的优惠券
        CouponEntity couponEntity = new CouponEntity();
        couponEntity.setCouponName("满100-10");//优惠券的名字
        return R.ok().put("coupons",Arrays.asList(couponEntity));
    }
  • 在member的主启动类上加注解@EnableDiscoveryClient,告诉member是一个远程调用客户端,member要调其他服务
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients(basePackages="com.xmh.gulimall.member.feign")//扫描接口方法注解
public class GulimallMemberApplication {
    public static void main(String[] args) {
        SpringApplication.run(GulimallMemberApplication.class, args);
    }
}
  • com.atguigu.gulimall.member.feign中新建接口CouponFeignService
@FeignClient("gulimall-coupon")//告诉spring cloud这个接口是一个远程客户端,要调用coupon服务(nacos中找到)
public interface CouponFeignService {

    // 远程服务的url
    @RequestMapping("/coupon/coupon/member/list")//注意写全优惠券类上还有映射
    public R membercoupons();//得到一个R对象
}
  • 在member的MemberController写一个测试
    @Autowired
    private CouponFeignService couponFeignService; //注入刚才的CouponFeignService接口

    @RequestMapping("/coupons")
    public R coupons(){
        MemberEntity memberEntity = new MemberEntity();
        memberEntity.setNickname("会员昵称张三");
        R membercoupons = couponFeignService.membercoupons();

        return R.ok().put("member", memberEntity).put("coupons", membercoupons.get("coupons"));
    }

  • 启动gulimall-member,gulimall-coupon项目。访问http://localhost:8000/member/member/coupons测试
    在这里插入图片描述
    测试成功

3.nacos用作配置中心

1.common中添加依赖 nacos配置中心

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

2.在coupons项目中创建/src/main/resources/bootstrap.yml,优先级别application.properties高

# 改名字,对应nacos里的配置文件名
spring:
  application:
    name: gulimall-coupon
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml # 指定配置文件为yaml格式

3.浏览器去nacos里的配置列表,点击+号,data ID:gulimall-coupon.yaml,进行配置
【谷粒商城】_第20张图片
4.在controller中编写测试代码

    @Value("${coupon.user.name}")
    private String name;
    
    @Value("${coupon.user.age}")
    private int age;

    @RequestMapping("/nacos")
    public R nacos(){
        return R.ok().put("name", name).put("age", age);
    }

5.访问http://localhost:7000/coupon/coupon/nacos测试
在这里插入图片描述
6.在coupon的控制层上加@RefreshScope支持动态刷新
【谷粒商城】_第21张图片
7.新建coupon、member、order、product、ware五个命名空间分别保存自己的配置文件

常见方案:每个微服务创建自己的命名空间,然后使用配置分组区分环境(dev/test/prod)

4.网关gateway

网关是请求流量的入口,常用功能包括路由转发,权限校验,限流控制等

使用spring cloud的gateway组件做网关功能

https://spring.io/projects/spring-cloud-gateway
参考手册:https://cloud.spring.io/spring-cloud-gateway/2.2.x/reference/html/

三大核心概念:

  • Route:发一个请求给网关,网关要将请求路由到指定的服务。路由有id,目的地uri,断言的集合,匹配了断言就能到达指定位置
  • Predicate断言:就是java里的断言函数,匹配请求里的任何信息,包括请求头等。根据请求头路由哪个服务
  • Filter:过滤器请求和响应都可以被修改
    客户端发请求给服务端。中间有网关。先交给映射器,如果能处理就交给handler处理,然后交给一系列filer,然后给指定的服务,再返回回来给客户端
    【谷粒商城】_第22张图片

1.新建模块gulimall-gateway作为网关
引入依赖

    <dependencies>
        <dependency>
            <groupId>com.xmh.gulimall</groupId>
            <artifactId>gulimall-common</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>

在nacos上新建gateway命名空间,在命名空间中新建配置gulimall-gateway.yaml
【谷粒商城】_第23张图片
配置application.yml

server:
  port: 88
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
  application:
    name: gulimall-gateway

配置bootstrap.yml

spring:
  application:
    name: gulimall-gateway
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml
        namespace: d717d0ee-7a07-4125-9881-3ef57d696ad3

主启动类

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) //不用数据源,过滤掉数据源配置
@EnableDiscoveryClient
public class GulimallGatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GulimallGatewayApplication.class, args);
    }
}

2.测试访问http://localhost:88?url=baidu 切换到百度, http://localhost:88?url=qq 切换到qq

在网关的application.yml中配置路由

server:
  port: 88
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      routes:
        - id: baidu_route              # 每一个路由的名字,唯一即可
          uri: https://www.baidu.com   # 匹配后提供服务的路由地址
          predicates:                 # 断言规则
            - Query=url,baidu         #如果url参数等于baidu 符合断言,转到uri

        - id: qq_route                  # 每一个路由的名字,唯一即可
          uri: https://www.qq.com   # 匹配后提供服务的路由地址
          predicates: # 断言规则
            - Query=url,qq         #如果url参数等于baidu 符合断言,转到uri

  application:
    name: gulimall-gateway

启动网关,访问http://localhost:88?url=baidu测试,成功

跳转到百度,测试成功

你可能感兴趣的:(项目,java)