SpringCloud Alibaba - 总结

文章目录

1. 环境搭建

1.1 centos7安装docker

安装官网:https://docs.docker.com/engine/install/centos/

# 卸载旧版本的docker
sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
                  
sudo yum install -y yum-utils
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo   
    
sudo yum install docker-ce docker-ce-cli containerd.io
# 启动docker
sudo systemctl start docker
# 设置开机自启动
sudo systemctl enable docker
# 查看docker安装版本
docker -v
# 查看docker下的容器
sudo docker images

# 配置docker阿里云镜像加速:https://cr.console.aliyun.com/cn-qingdao/instances/mirrors
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://chqac97z.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

1.2 docker安装MySQL5.7

# 下载MySQL5.7容器
sudo docker pull mysql:5.7

# 检查下载的容器
sudo docker images

# --name指定容器名字 -v目录挂载 -p指定端口映射  -e设置mysql参数(密码为root) -d后台运行
sudo docker run -p 3306: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

# 查看运行中的容器
docker ps

# 配置MySQL
vi /mydata/mysql/conf/my.conf 

# 插入下面的内容
[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

# 重启MySQL
docker restart mysql

1.3 docker安装Redis

# 在虚拟机中
mkdir -p /mydata/redis/conf

touch /mydata/redis/conf/redis.conf

docker pull redis

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 

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

# 进入Redis的配置文件,使得数据持久化
vim /mydata/redis/conf/redis.conf

# 插入下面内容
appendonly yes

# 重启redis
docker restart redis

如果出现问题,可以删除容器和镜像重新安装:

# 停止启动的容器
docker stop CONTAINER ID
# 删除容器
docker rm CONTAINER ID
# 删除镜像
docker rmi IMAGE ID  

1.4 环境安装配置

① 配置maven

② 给idea装两个插件:lombok,MybatisX

③ 安装vscode,并安装插件

④ 配置git:

$ git config --global user.name "hengheng"
$ git config --global user.email "18751887307@163.co"
$ ssh-keygen -t rsa -C "18751887307@163.com"
# 配置码云上的ssh密钥
$ cat ~/.ssh/id_rsa.pub
# 测试是否配置成功
$ ssh -T git@gitee.com

⑤ 项目结构创建:

商品服务product、仓储服务ware、订单服务order、优惠券服务coupon、会员服务member

SpringCloud Alibaba - 总结

1.5 数据库初始化

sudo docker ps
sudo docker ps -a
# 这两个命令的差别就是后者会显示  【已创建但没有启动的容器】

# 我们接下来设置我们要用的容器每次都是自动启动
sudo docker update redis --restart=always
sudo docker update mysql --restart=always
# 如果不配置上面的内容的话,我们也可以选择手动启动
sudo docker start mysql
sudo docker start redis
# 如果要进入已启动的容器
sudo docker exec -it mysql /bin/bash

创建数据库及数据库表:

gulimall-oms、gulimall-pms、gulimall-sms、gulimall-ums、gulimall-wms

SpringCloud Alibaba - 总结

2. 快速开发

2.1 人人开源

① 在码云上搜索人人开源,我们使用renren-fast,renren-fast-vue项目,启动renren-fast访问localhost:8080

https://gitee.com/renrenio,将这两个项目克隆下来,然后删除.git文件后放入后端项目gulimall中

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

② 配置前端工程:

下载nodejs并配置npm镜像:

node -v
npm config set registry http://registry.npm.taobao.org/

在VSCode的终端运行:

npm install

如果运行报错:npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。右击vscode,选择一管理员身份运行,即可解决问题。

安装失败,按照下面方式重新安装,安装成功:

# 先清除缓存
npm rebuild node-sass
npm uninstall node-sass

然后在VS Code中删除node_modules

# 执行
npm i node-sass --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/

# 如果上面没有报错,就继续执行
npm install 

# 运行项目
npm run dev 

访问http://localhost:8001/#/login,输入admin和admin即可登录后台管理系统,实现前后端联调。

2.2 逆向工程生成5个微服务crud代码

将代码生成器项目克隆下来,然后删除.git文件,并放到项目工程下

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

在application.yml中配置MySQL,先生成gulimall_pms的项目代码:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    #MySQL配置
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.38.22:3306/gulimall_pms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: root

④ 测试类:加入@RunWith(SpringRunner.class)注解,否则@Autowired注解无法完成属性注入

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = GulimallProductApplication.class)
public class GulimallProductApplicationTests {
    @Autowired
    private BrandService brandService;
}

⑤ 插入数据库中的数据中文乱码,只需要在product项目的application.yml中配置编码即可

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://192.168.38.22:3306/gulimall_pms?useUnicode=true&characterEncoding= utf-8
    driver-class-name: com.mysql.jdbc.Driver

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

⑥ 使用逆向工程生成所有微服务项目代码,修改renren-generator项目的配置文件:

修改generator.properties:

mainPath=com.atguigu
package=com.atguigu.gulimall
# 将模块名称修改为coupon
moduleName=coupon
author=hengheng
email=hengheng@gmail.com
# 将表头修改为sms_
tablePrefix=sms_

修改application.yml:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.jdbc.Driver
    # 将数据库修改为gulimall_sms
    url: jdbc:mysql://192.168.38.22:3306/gulimall_sms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: root

3. SpringCloud Alibaba

https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md

在gulimall-common的项目中引入坐标:

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

3.1 Nacos 注册中心

下面以coupon服务为例,将gulimall-coupon服务注册进nacos:

① 在gulimall-common模块中引入 Nacos Discovery Starter,这样每个服务中都会引入相应的坐标

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

② 在gulimall-coupon服务的配置文件中配置 Nacos Server 地址:

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

③ 在gulimall-coupon服务中使用 @EnableDiscoveryClient 注解开启服务注册与发现功能:

@SpringBootApplication
@EnableDiscoveryClient
public class GulimallCouponApplication {
    public static void main(String[] args) {
        SpringApplication.run(GulimallCouponApplication.class, args);
    }
}

④ 启动项目,访问http://localhost:8848/nacos/

SpringCloud Alibaba - 总结

同样,将gulimall-member服务也注册进注册中心:

SpringCloud Alibaba - 总结

3.2 Openfeign 远程调用

需求:gulimall-member会员服务远程调用gulimall-coupon会员服务

① 在member会员服务中引入openfeign坐标 :

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

② 在优惠卷gulimall-coupon中编写一个请求,让gulimall-member会员服务通过openfeign远程调用这个接口:

@RequestMapping("coupon/coupon")
public class CouponController {
    @Autowired
    private CouponService couponService;

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

③ 在gulimall-member服务中编写一个接口,用来调用远程服务业务:

//指定要调用的注册中心的服务的服务名
@FeignClient("gulimall-coupon")
public interface CouponFeignService {
    //这个就是要调用的gulimall-coupon中的接口方法
    @RequestMapping("/coupon/coupon/member/list")
    public R membercoupons();
}

④ 主启动类开启远程服务调用功能:

//开启远程调用功能,服务启动时会自动扫描带有@FeignClient注解的方法
//每个方法中指定了被调用的远程服务的方法
@EnableFeignClients("com.atguigu.gulimall.member.feign")
@EnableDiscoveryClient
@SpringBootApplication
public class GulimallMemberApplication {
    public static void main(String[] args) {
        SpringApplication.run(GulimallMemberApplication.class, args);
    }
}

⑤ gulimall-member中编写一个请求方法实现远程调用:

@RestController
@RequestMapping("member/member")
public class MemberController {
    @Autowired
    CouponFeignService couponFeignService;
    
    @RequestMapping("/coupons")
    public R test(){
        MemberEntity memberEntity = new MemberEntity();
        memberEntity.setNickname("张三");
        //调用couponFeignService接口中的方法
        R membercoupons = couponFeignService.membercoupons();
        return R.ok().put("member",memberEntity).put("coupons",membercoupons.get("coupons"));
    }
}

⑥ 报错,巨坑:因为我创建服务的时候没有勾选openfeign,导致引入依赖后相关注解不识别,后来导入openfeign坐标时指明版本号,但是启动项目后访问报错500,后面通过这样解决了:

在pom文件中添加:

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

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

⑦ 测试,访问http://localhost:8000/member/member/coupons

SpringCloud Alibaba - 总结

3.3 Nacos配置中心

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

下面以coupon服务为例:

① 首先,在gulimall-common服务中引入 Nacos Config Starter:

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

② 在gulimall-coupon服务模块的bootstrap.properties中配置数据:

# 指代服务名称
spring.application.name=gulimall-coupon
# 指定配置中心服务器地址,nacos服务器就是一个配置中心
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

③ 创建一个配置列表,Data ID默认为:spring.application.name.properties(spring.application.name.yml)

SpringCloud Alibaba - 总结

④ 从Nacos Config 中获取相应的配置,这里我们使用 @Value 注解来将对应的配置注入到Controller 的 userName 和 age 字段,并添加 @RefreshScope 打开动态刷新功能。

@RefreshScope
@RestController
@RequestMapping("coupon/coupon")
public class CouponController {
    @Autowired
    private CouponService couponService;

    @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);
    }
}

⑤ 测试,访问http://localhost:7000/coupon/coupon/test

3.4 Nacos配置中心-命名空间与配置分组

① Data ID相同,命名空间不同,启动服务访问http://localhost:7000/coupon/coupon/test,默认加载public命名空间的配置:

SpringCloud Alibaba - 总结

如果想要加载dev命名空间的配置,只需要在bootstrap.properties中添加配置:

spring.cloud.nacos.config.namespace=b2add807-4c38-43f0-be83-d5ee4fcaea57

② 也可以为每一个微服务创建一个命名空间,这样启动服务时就会只加载该命名空间的配置文件

SpringCloud Alibaba - 总结

将该命名空间配置在bootstrap.properties文件中:

spring.cloud.nacos.config.namespace=8c2dbbf4-986a-4485-a1b2-06bb3fa2472f

这样以后这个服务启动的时候就会加载coupon命名空间下的配置。

③ Data ID相同,group不同:

SpringCloud Alibaba - 总结

在bootstrap.properties中配置group:

spring.cloud.nacos.config.group=dev

3.5 Nacos配置中心-加载多配置集

需求:将application.yml配置文件中的内容都放在配置中心的配置文件中,进热代替application.yml文件

① 将与数据源有关的配置放到coupon命名空间的配置中:

SpringCloud Alibaba - 总结

② 将于mybatis相关的配置放到coupon命名空间的配置中:
SpringCloud Alibaba - 总结

③ 将其他相关配置放到coupon命名空间的配置中:

SpringCloud Alibaba - 总结

④ 在bootstrap.properties中配置要加载的配置文件:

spring.application.name=gulimall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=8c2dbbf4-986a-4485-a1b2-06bb3fa2472f
spring.cloud.nacos.config.group=test

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
# 动态刷新,默认为false
spring.cloud.nacos.config.ext-config[2].refresh=true

3.6 GataWay网关

发送请求需要知道商品服务的地址,如果商品服务器有123服务器,1号掉线后,还得改,所以需要网关动态地管理,他能从注册中心中实时地感知某个服务上线还是下线。请求也要加上询问权限,看用户有没有权限访问这个请求,也需要网关。

https://cloud.spring.io/spring-cloud-gateway/2.2.x/reference/html/

① 创建gulimall-gateway项目,同时添加pom文件:

<dependency>
    <groupId>com.atguigu.gulimall</groupId>
    <artifactId>gulimall-common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

② 编写注册中心的配置文件application.properties:

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

③ 编写配置中心的配置文件bootstrap.properties:

spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=fc4f6402-947a-4363-a088-a84576024445

SpringCloud Alibaba - 总结

④ 主配置类中引入注册发现注解@EnableDiscoveryClient,用于发现其他服务:

@EnableDiscoveryClient
//因为引入了mybatis坐标,而又不需要数据库,所以需要排除,否则启动报错
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class GulimallGatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GulimallGatewayApplication.class, args);
    }
}

⑤ 编写application.yml,来完成需求:

spring:
  cloud:
    gateway:
      routes:
        - id: test_route
          uri: https://www.baidu.com/
          predicates:
            - Query=url,baidu  # 访问url=baidu,就会路由到百度网页
        - id: qq_route
          uri: https://www.qq.com/
          predicates:
            - Query=url,qq     # 访问url=qq,就会路由到qq网页

访问:http://localhost:88/hello?url=qq

上一篇:注册登录篇-注册


下一篇:【项目系列】- 谷粒商城基础篇(二刷)