尚硅谷2020微服务分布式电商项目《谷粒商城》(Alibaba+Vue)开发教程学习笔记(一)

前言:无意中看到尚硅谷发布了最新的微服务分布式项目《谷粒商城》,刚好最近在学习微服务,所以,想要学习一下。

官方已经发布了相关的资料,但是,可惜的是,并没有课件,只能跟着视频教程一步一步的学习,所以,将目前学习的笔记整理,供自己日后复习,供大家参考。若有不足,还请指正。

一、开发环境统一

0、安装虚拟机、安装MySQL、安装Redis

因为我不打算在我本地电脑上安装这些,所以这条内容省略。

1、Maven

(1)使用阿里镜像仓库

    <!-- 阿里镜像仓库-->
    <mirror>
        <id>alimaven</id>
        <name>aliyun maven</name>
        <url>
            http://maven.aliyun.com/nexus/content/groups/public/
        </url>
        <mirrorOf>central</mirrorOf>
    </mirror>

(2)使用jdk1.8编译

<profile>
    <id>jdk‐1.8</id>
    <activation>
        <activeByDefault>true</activeByDefault>
        <jdk>1.8</jdk>
    </activation>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
    </properties>
</profile>

2、安装vscode,并安装相关插件

3、安装配置git

git我之前已经安装过了,这里就不说了。

跟视频一样吧,也使用码云,注册就不说了。

不过,这里要注意一个问题,也就是多个git ssh key 管理问题

不然,会提示:permission denied错误。

因为我之前有其他git账号的ssh key存在,比如GitHub,这里在生成ssh key时,不能一路回车

ssh-keygen -t rsa -C "[email protected]"  <<<这里不能一路回车,第一个交互提示要输入存放的路径,不能用默认的,否则会覆盖原来的其他的账号key

下面说下,关于管理多个git ssh key的问题

在.ssh目录创建config文本文件并完成相关配置(最核心的地方)

内容说明如下:

HostName           这个是真实的域名地址
IdentityFile          这里是id_rsa的地址
PreferredAuthentications   配置登录时用什么权限认证--可设为publickey,password publickey,keyboard-interactive等
User            配置使用用户名

这里我的是:

# 配置github.com
Host github.com                 
    HostName github.com
    IdentityFile C:\Users\abc\.ssh\github_rsa
    PreferredAuthentications publickey
    User myname

# 配置gitee.com    
Host gitee.com    
    HostName gitee.com   
    IdentityFile C:\Users\abc\.ssh\gitee_rsa
    PreferredAuthentications publickey
    User myname

之后,通过这个命令来测试:ssh -T [email protected]

参考:

https://blog.csdn.net/weixin_36995644/article/details/81776412

https://www.cnblogs.com/popfisher/p/5731232.html

4.项目初始结构创建

在gitee上创建仓库,并且在IDEA中clone,并创建member会员服务,ware仓储服务,order订单服务,product产品服务,coupon优惠券服务,修改.gitignore文件,增加以下内容忽略这些文件的修改。

**/mvnw
**/mvnw.cmd

**/.mvn
**/target/

.idea

**/.gitignore

最后,再把代码提交到gitee仓库中。

5.数据库初始化

根据提供的SQL文件,分别创建gulimall各个表。

二、快速开发-使用人人开源搭建后台管理系统

1.git clone下载renren-fast, renren-fast-vue,renren-generator仓库代码

https://gitee.com/renrenio/renren-fast.git

https://gitee.com/renrenio/renren-fast-vue.gi

https://gitee.com/renrenio/renren-generator.git

2.将renren-fast代码放到gulimall工程目录下面,并在总工程的pom.xml引入renren-fast module.

3.执行renren-fast模块种的db文件下的mysql.sql语句

注意,创建的数据库的基字符集使用utf8mb4。

4.修改renren-fast的application-dev.yml语句中的如下信息

url: jdbc:mysql://172.0.1.xx:3306/gulimall_admin
username: root
password: 123456

启动renren-fast应用

注意,这里遇到一个错误,就是application-dev.yml文件中的com.alibaba.druid.pool.DruidDataSource 显示红色,出错。
另外,一个就是RenrenApplication.java中String标红,显示需要导入包。原来是这个module没有设置对应的jdk,设置一下jdk8就没问题了。

5.安装Node.js,配置npm使用淘宝镜像

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

6.用vscode打开renren-fast-vue代码,在终端执行:npm install 下载安装依赖,
如果下载出错,可以使用cnpm install 下载,在下载完成后,执行:npm run dev 启动

7.renren-generator代码导入到我们的项目,并启动

8.使用renren-generator结合renren-fast-vue,根据数据库,反向生成product模块代码,并把main文件copy覆盖product下面的main文件夹。

9..新建gulimall-common模块,把公共的API等信息放到common模块中,并解决product中代码引用包的问题。

10.如法炮制,依次使用人人开源产生代码,覆盖main,并导入gulimall-common这类。

11.使用MyBatis-Plus,测试数据库读写问题

(1)导入依赖,在gulimall-common模块的pom.xml中加入:

<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-boot-starter</artifactId>
	<version>3.2.0</version>
</dependency>

(2)在gulimall-product的application.yml文件增加以下内容:

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://172.0.1.xx:3306/gulimall_pms?characterEncoding=UTF-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    #driver-class-name: com.mysql.jdbc.Driver

mybatis-plus:
  mapper-locations: classpath*:/mapper/**/*.xml
  global-config:
    db-config:
      id-type: auto

(3)在GulimallProductApplicationTests.java中,如下:

@SpringBootTest
class GulimallProductApplicationTests {
    @Autowired
    BrandService brandService;

    @Test
    void contextLoads() {
//        BrandEntity brandEntity = new BrandEntity();
//        brandEntity.setBrandId(4L);
//        brandEntity.setDescript("华为");

//        brandEntity.setName("华为");
//        brandService.save(brandEntity);
//        System.out.println("保存成功...");

//        brandService.updateById(brandEntity);

        List<BrandEntity> list = brandService.list(new QueryWrapper<BrandEntity>().eq("brand_id", 4L));
        list.forEach((item) -> {
            System.out.println(item);
        });
    }

}

(4)启动GulimallProductApplicationTests方法,依次测试上面的save方法,update方法,以及遍历方法,可以看到数据库中的数据是正确的。

(5)使用总结

/*
 1、整合MyBatis-Plus
 (1)、导入依赖
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>
  (2)、配置
    1、配置数据源
        1)、导入数据库的驱动
        2)、在application.yml配置数据源相关信息
    2、配置Mybatis-Plus
        1)、使用MapperScan
        2)、告诉MyBatis-Plus,sql映射文件位置
 */

注意,这里有两个问题:
(1)启动整个测试类,application.yml中的driver-class-name: com.mysql.jdbc.Driver 提示报警,应该使用driver-class-name: com.mysql.cj.jdbc.Driver
(2)数据库写入出现乱码,应该把application.yml中的url改为:
url: jdbc:mysql://172.0.1.xx:3306/gulimall_pms?characterEncoding=UTF-8
 

至此,整个项目基本环境已经弄好了。

三、引入SpringCloudAlibaba组件

1.SpringCloudAlibaba版本引用

在gulimall-common的pom.xml文件中引入spring-cloud-alibaba,如下:

<dependencyManagement>
        <!-- spring cloud alibaba 2.1.0.RELEASE -->
        <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>

2.引入Alibaba Nacos注册中心

配置参考:https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/readme-zh.md

(1)引入Nacos Discovey,在gulimall-common的pom.xml文件中加上以下内容:

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

(2)下载Nacos server,我下载的是1.1.4版本,解压后,执行bin目录下面的startup.cmd文件启动。

(3)在应用中配置指定Nacos server注册中心地址,以gulimall-coupon模块说明,在application.yml文件中添加如下内容:

spring:
    cloud:
        nacos:
          discovery:
            server-addr: 127.0.0.1:8848
    application:
    	name: gulimall-coupon

(4)使用@EnableDiscoveryClient注解开启服务注册于发现功能

(5)启动gulimall-coupon服务(注意Nacos Server要先启动),访问本地连接:http://localhost:8848/nacos/#/serviceManagement?dataId=&group=&appName=&namespace=,会看到服务列表里面出现gulimall-coupon

3.在gulimall-member远程调用gulimall-coupon模块的服务

(1)openfeign声明式远程调用引入,在gulimall-member模块的pom.xml文件加入以下内容:

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

(2)在CouponController.java加上远程调用的方法实现

@RequestMapping("/member/list")
public R membercoupons() {
    CouponEntity couponEntity = new CouponEntity();
    couponEntity.setCouponName("满100减50");
    return R.ok().put("coupons", Arrays.asList(couponEntity));
}

(3)在gulimall-member模块下,建立一个接口CouponFeignService.java,并写上上面实现的远程调用的API。

package com.atguigu.gulimall.member.feign;

import com.atguigu.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 这是一个声明式的远程调用
 */
@FeignClient("gulimall-coupon")
public interface CouponFeignService {

    @RequestMapping("/coupon/coupon/member/list")
    public R membercoupons();
}

(4)在GulimallMemberApplication.java中添加@EnableFeignClients(basePackages = "com.atguigu.gulimall.member.feign") ,这个注解的作用是让springcloud扫描com.atguigu.gulimall.member.feign包下的所有接口

/**
 * 1、想要远程调用别的服务
 * 1)、引入open-feign
 * 2)、编写一个接口,告诉SpringCloud这个接口需要调用远程服务
 *  1、声明接口的每一个方法都是调用哪个远程服务的那个请求
 * 3)、开启远程调用功能
 */
@EnableFeignClients(basePackages = "com.atguigu.gulimall.member.feign")
@EnableDiscoveryClient
@SpringBootApplication
public class GulimallMemberApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimallMemberApplication.class, args);
    }

}

(5)在gulimall-member模块下的controller数据包写一个测试方法来调用这个远程服务API,比如:在MemberController.java中写一个测试方法,如下:

@Autowired
CouponFeignService couponFeignService;

@RequestMapping("/coupons")
public R test() {
    MemberEntity memberEntity = new MemberEntity();
    memberEntity.setNickname("张三");

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

(6)启动gulimall-coupon和gulimall-member这两个微服务,访问测试API的地址:http://localhost:8000/member/member/coupons,即可以看到能访问到数据。

4.引入Alibaba Nacos配置中心

参考地址:https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/readme-zh.md

(1)导入Nacos配置中心,在gulimall-common的pom.xml文件中加上以下内容:

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

(2)gulimall-coupon模块西安的resource目录下新建文件bootstrap.properties,内容如下:

spring.application.name=gulimall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

(3)在gulimall-coupon模块下的application.properties中加入以下配置:

coupon.user.name=zhangsan
coupon.user.age=18

(4)写测试方法,在CouponController.java中加入以下内容:

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

@Value("${coupon.user.age}")
private Integer age;

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

(5)启动coupon服务,访问链接:http://localhost:7000/coupon/coupon/test,即可以看到上面的配置
(6)但是,这种方法有一个问题,就是如果配置改变了,需要修改application.properties,并重启coupon微服务,这是个不好的,所以我们引入了Nacos配置中心。根据启动log,微服务可以从nacos读取配置文件信息,默认的是:gulimall-coupon.properties。
(7)在http://localhost:8848/nacos的配置列表中,新建配置,Data Id为:gulimall-coupon.properties,规则就是,应用名.properties,在里面添加任意配置内容,比如:

coupon.user.name=zhangsan2
coupon.user.age=24

(8)在上面的test()方法所在的类上标注@RefreshScope,这样,当Nacos配置中心的gulimall-coupon.properties配置内容修改了,微服务就可以动态的获取到最新的配置信息,并且,这个优先级是高于微服务本身的配置的。
(9)使用Nacos作为配置中心的使用总结如下:

/**
 * 1、如何使用Nacos作为配置中心统一管理配置
 *  1)、引入依赖
 *  <dependency>
 *      <groupId>com.alibaba.cloud</groupId>
 *      <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
 *  </dependency>
 *  2)、创建一个bootstrap.properties,内容如下:
 *      spring.application.name=gulimall-coupon
 *      spring.cloud.nacos.config.server-addr=127.0.0.1:8848
 *  3)、需要给配置中心添加一个叫 数据库集(Data Id)gulimall-coupon.properties,默认规则:yingyongming.properties
 *  4)、给应用名.properties添加任何配置
 *  5)、动态获取配置。
 *      @RefreshScope:动态获取并刷新配置
 *      @Value("${配置项的名}"):获取到配置
 *      如果配置中心和当前应用的配置文件都配置了相同的项,优先使用配置中心的配置
 *
 */

5.Nacos作为配置中心的更多细节用法
(1)为了区分配置和隔离,Nacos引入了几个概念:

  • 命名空间,用作配置隔离,默认:public(保留空间):默认新增的所有配置都在public空间,开发,测试,生产:利用命名空间来做环境隔离,或者,每一个微服务之间相互隔离配置,每个微服务都创建自己的命名空间,只加载自己命名空间下的所有配置。
  • 配置集以及配置ID,配置集就是所有配置的集合,配置集ID类似文件名,也就是Nacos 中的Data ID。
  • 配置分组,默认所有的配置分组都属于:DEFAULT_GROUP,当然,也指定自己的配置分组,比如1111双十一,618之类的。

在之前已经提到,在默认public命名空间,以及使用默认的分组DEFAULT_GROUP里面,创建Data ID:gulimall-coupon.properties,然后在bootstrap.properties文件里面添加指定Nacos的地址,就可以访问默认的gulimall-coupon.properties里面的配置信息了,这个是默认的规则。

但是,如果我们想要用自己的,不是default默认的配置怎么处理呢?

比如还是gulimall-coupon.properties这个Data ID,但是放在了另外一个命名空间,比如是coupon(对应微服务模块的名称,可以每个微服务建立一个对应的命名空间),而且放在了一个prod分组里面(类似的,同一个coupon命名空间下面,还可以建立dev分组,test分组等),那么如何在微服务里面指定访问这个配置呢?答案是:在bootstrap.properties里面添加指定对应的namespace和group,如下:

spring.application.name=gulimall-coupon

spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=9bc589c6-3f38-470b-af8d-fe84f04770ef
spring.cloud.nacos.config.group=prod

9bc589c6-3f38-470b-af8d-fe84f04770ef是Nacos上coupon命名空间对应的ID值。prod则对应prod这个配置分组,这样,当微服务启动时,如果要获取的配置在Nacos配置中心有(也就是这里的gulimall-coupon.properties)的话,那么就优先使用配置中心的,否则,就会使用代码中application.properties文件的配置。

(2)同时加载多个配置(新的知识点)
注意一下,我们之前是把所有的配置都放在了application.yml中,比如:

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://172.0.1.172:3306/gulimall_sms?characterEncoding=UTF-8
    driver-class-name: com.mysql.cj.jdbc.Driver
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
  application:
    name: gulimall-coupon

mybatis-plus:
  mapper-locations: classpath*:/mapper/**/*.xml
  global-config:
    db-config:
      id-type: auto

server:
  port: 7000

但是,如果配置很多的话,都同在同一个文件中的话,不好看,也不便于配置,所以,建议按照不同的作用写到几个配置文件中,而微服务也会从Nacos配置文件中读取配置,并且Nacos也支持多配置文件读取,那么怎么配置使用呢?
在上面我们提到了新建了coupon这个命名空间对应gulimall-coupon这个模块,那么我们把上面的application.yml配置按照不同的功能,拆分为三个配置文件配置到Nacos中,放在coupon命名空间,dev配置分组下面,它们分别是:datasource.yml,内容如下:

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://172.0.1.xx:3306/gulimall_sms?characterEncoding=UTF-8
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis.yml文件,内容如下:

mybatis-plus:
  mapper-locations: classpath*:/mapper/**/*.xml
  global-config:
    db-config:
      id-type: auto

以及other.yml,内容如下:

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
  application:
    name: gulimall-coupon


server:
  port: 7000

而使用的话,很简单,在上面bootstrap.properties文件的基础上增加一下内容:

spring.cloud.nacos.config.ext-config[0].data-id=datasource.yml
spring.cloud.nacos.config.ext-config[0].group=dev
spring.cloud.nacos.config.ext-config[0].refresh=true

spring.cloud.nacos.config.ext-config[1].data-id=mybatis.yml
spring.cloud.nacos.config.ext-config[1].group=dev
spring.cloud.nacos.config.ext-config[1].refresh=true

spring.cloud.nacos.config.ext-config[2].data-id=other.yml
spring.cloud.nacos.config.ext-config[2].group=dev
spring.cloud.nacos.config.ext-config[2].refresh=true

分别制定要导入的配置名称,所在的配置分组group,已经是否动态刷新(refresh)。
最好,把application.yml中的配置全部注释掉,启动coupon微服务,来验证配置。可以发现,微服务能够正常读取Nacos中的这三个配置文件。
对于这两部分内容,总结起来就是:

/**
 * 1、如何使用Nacos作为配置中心统一管理配置
 *  1)、引入依赖
 *  <dependency>
 *      <groupId>com.alibaba.cloud</groupId>
 *      <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
 *  </dependency>
 *  2)、创建一个bootstrap.properties,内容如下:
 *      spring.application.name=gulimall-coupon
 *      spring.cloud.nacos.config.server-addr=127.0.0.1:8848
 *  3)、需要给配置中心添加一个叫 数据库集(Data Id)gulimall-coupon.properties,默认规则:yingyongming.properties
 *  4)、给应用名.properties添加任何配置
 *  5)、动态获取配置。
 *      @RefreshScope:动态获取并刷新配置
 *      @Value("${配置项的名}"):获取到配置
 *      如果配置中心和当前应用的配置文件都配置了相同的项,优先使用配置中心的配置
 *
 * 2、细节
 *  1)、命名空间,配置隔离
 *      默认:public(保留空间):默认新增的所有配置都在public空间
 *      1、开发,测试,生产:利用命名空间来做环境隔离
 *         注意,在bootstrap.properties 配置上,需要使用哪个命名空间下的配置。
 *         spring.cloud.nacos.config.namespace=32c4a90d-6ac4-4f04-b050-e09bbe7bd58f
 *      2、每一个微服务之间相互隔离配置,每个微服务都创建自己的命名空间,只加载自己命名空间下的所 
 *         有配置
 *
 *  2)、配置集:所有配置的集合
 *
 *  3)、配置集ID:类似文件名
 *      Data ID: 类似文件名
 *
 *  4)、配置分组:
 *      默认所有的配置集都属于:DEFAULT_GROUP
 *      1111,618
 *
 *  每个微服务创建自己的命名空间,使用配置分组区分环境,dev、test、prod
 *
 *  3、同时加载多个配置文件
 *   1)、微服务任何配置信息,任何配置文件都可以放在配置中心中
 *   2)、只需要在bootstrp.properties说明加载配置中心那些配置文件即可
 *   3)、@Value、@ConfigurationProperties...
 *   以上SprintBoot任何方法从配置文件中获取值,都能使用
 *   配置中心有的优先使用配置中心中的
 *
 */

6.SpringCloud Gateway网关
(1)Gateway网关简单介绍
网关作为流量的入口,常用功能包括路由转发、权限校验、流量控制等,而SpringCloud gateway作为SpringCloud官方推出的第二代网关框架,取代了Zuul网关。
简单一句话总结:先断言(判断请求是否符合某个路由规则),(如果符合了某个路由规则)再路由到指定地方,但在路由之前要先过滤。

官方文档:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.2.RELEASE/reference/html/

(2)引入gulimall-gateway模块

新建gulimall-gateway模块,用Spring Initaliz的方法,并导入gateway模块,建好后,在pom.xml中导入gulimall-common的模块依赖。

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

gulimall-gateway模块,同样需要注册到Nacos注册中心和配置中心,下面先弄注册到Nacos注册中心的配置,需要在application.properties文件中指定Nacos注册中心的地址

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

而要使用Nacos配置中心,需要在bootstrap.properties文件中指定Nacos配置中心的地址:

spring.application.name=gulimall-gateway

spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=7df3fe8a-4e08-46d5-8535-da50e6834bfb

这里的7df3fe8a-4e08-46d5-8535-da50e6834bfb是指Nacos配置中心的gateway命名空间所对应的ID。

最后,在application.yml中写上gateway使用的配置规则,比如路由,断言,过滤等。比如:

spring:
  cloud:
    gateway:
      routes:
        - id: test_route
          uri: https://www.baidu.com
          predicates:
            - Query=url,baidu
        - id: qq_route
          uri: https://www.qq.com
          predicates:
            - Query=url,qq

访问:http://localhost:88/hello?url=qq,就会转到这qq个url地址:https://www.qq.com/hello,同样的,访问:http://localhost:88/hello?url=baidu,就会转到百度的url地址.

至此,关于的SpringCloud Alibaba的基本使用告一段落。

接下来,就是前端的基本知识学习,由于篇幅的限制等原因,就另外开专门开一篇文章来做前端的笔记。

尚硅谷2020微服务分布式电商项目《谷粒商城》(Alibaba+Vue)开发教程学习笔记(二)

https://blog.csdn.net/ok_wolf/article/details/105456170

发布了16 篇原创文章 · 获赞 5 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/ok_wolf/article/details/105400748
今日推荐