微服务(二)-Nacos注册中心、SpringGateway网关、前后端分离

1 Nacos注册中心

1.1 什么是Nacos?

  Nacos是Spring Cloud Alibaba提供的一个软件,Nacos可以负责对当前微服务项目进行注册和管理,也就是"注册中心"。

  Nacos是一个开发好的软件,不需要我们进行单独的配置,我们只需要学习如何安装 \ 启动 \ 使用它就可以了。

  要想安装并顺利启动Nacos,必须配置java的环境变量。

1.2 java环境变量配置

windows操作系统环境变量配置过程如下:

(1)在"计算机\此电脑\我的电脑"图标上点击右键,选择“属性”,在出来的页面选择“高级系统设置”

(2)点击环境变量

(3)检查是不是有JAVA_HOME的配置,并且配置的路径确实有jdk的文件内容,如果没有JAVA_HOME,点击新建并按要求配置即可。

  变量名:JAVA_HOME 【全部大写】

  变量值:jdk安装路径(我的安装路径:D:\Software_Development\JDK)

选中的jdk安装路径中应包含如下内容:

  上面就配置好了java的开发环境,接下来就可以运行nacos了。

1.3 安装启动Nacos

  安装非常简单,就是将压缩包解压,点开解压后nacos文件夹下的bin文件夹包含如下内容:

  其中,startup.cmd这个是Windows系统启动nacos的命令、shutdown.cmd这个是Windows系统停止nacos的命令,注意logs、work文件夹是之后生成的,最初解压时文件夹中并没有这两个文件夹。

注意:.sh结尾的一套是linux系统使用的。

  要启动nacos不能直接双击,需要使用dos命令来启动:Win+R 输入cmd, 进入dos操作窗口

  • 1.根据当前nacos文件夹所在位置切换盘符,格式:盘名:

  • 2.然后进入nacos解压文件夹所在的bin目录

  • 3.在bin路径下,输入启动命令:startup.cmd -m standalone,其中,standalone代表着单机模式运行,非集群模式。

  启动之后访问:http://localhost:8848/nacos,出现如下页面,进行登录,用户名和密码都是:nacos

  到此为止,nacos的安装和启动就完成了。

  注意:第一次登录时需要输入用户名和密码(均为nacos),之后登录就不再需要输入用户名和密码了,直接进入nacos登录成功首页。登录成功首页如下:

1.4 使用IDEA启动Nacos

  我们之前启动Nacos的方式过于复杂,每次启动都要编写启动代码,一不小心就写错,导致启动失败。

IDEA提供了方法帮助我们简单的启动nacos,步骤如下:

  (1)选择Edit Configurations...,点击“+”,找到Shell Script

  (2)设置名字为nacos(其他名字也可以),Script path填写startup.cmd的路径,记得写上standalone.cmd,Script options填写:-m standalone(严格书写,否则不能正常启动nacos)

  最好重启一下Idea确保IDEA使用了最新的环境变量,如果最开始安装jdk就配置了环境变量JAVA_HOME,现在就不需要重启IDEA了,可以直接启动nacos,之后就可以在IDEA中控制nacos的启动和关闭了。

  • 启动(启动前保证nacos只启动了一次,多次启动可能报错,关闭多余启动。先切换到nacos,再点击红色△)

 

  启动成功页面如下:

  • 关闭:直接点nacos X即可

1.5 注册项目到nacos

  今后我们要进行微服务项目的开发,所有当前项目的微服务项目(业务类)都要注册到nacos。

  我们现在以knows-resource为例,注册这个项目到nacos,在注册之前,我们需要很多SpringCloud以及SpringCloud Alibaba的依赖,这些依赖直接提供给大家。

  (1)新建Spring Initializr形式的父项目knows,设置Group、Artifict、Type(Maven POM)、Java Version、选择SpringBoot最低版本2.4.10,之后什么都不选,完成knows项目的创建。

  父项目knows的pom.xml文件内容如下:

 <?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>
     <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
         <version>2.3.12.RELEASE</version>
         <relativePath/> <!-- lookup parent from repository -->
     </parent>
     <groupId>cn.tedu</groupId>
     <artifactId>knows</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <name>knows</name>
     <description>Demo project for Spring Boot</description>
     <packaging>pom</packaging>
     <modules>
         <module>knows-resource</module>
     </modules>
     <properties>
         <java.version>1.8</java.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
         <spring-cloud-alibaba.version>2.2.2.RELEASE</spring-cloud-alibaba.version>
         <mybatis.plus.version>3.3.1</mybatis.plus.version>
         <pagehelper.starter.version>1.3.0</pagehelper.starter.version>
         <knows.commons.version>0.0.1-SNAPSHOT</knows.commons.version>
         <spring-cloud.version>Hoxton.SR3</spring-cloud.version>
         <spring-security-jwt.version>1.0.10.RELEASE</spring-security-jwt.version>
     </properties>
     <dependencies>
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
             <optional>true</optional>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
             <exclusions>
                 <exclusion>
                     <groupId>org.junit.vintage</groupId>
                     <artifactId>junit-vintage-engine</artifactId>
                 </exclusion>
             </exclusions>
         </dependency>
     </dependencies>
     <dependencyManagement>
         <dependencies>
             <dependency>
                 <groupId>cn.tedu</groupId>
                 <artifactId>knows-commons</artifactId>
                 <version>${knows.commons.version}</version>
             </dependency>
             <dependency>
                 <groupId>com.baomidou</groupId>
                 <artifactId>mybatis-plus-boot-starter</artifactId>
                 <version>${mybatis.plus.version}</version>
             </dependency>
             <dependency>
                 <groupId>com.baomidou</groupId>
                 <artifactId>mybatis-plus</artifactId>
                 <version>${mybatis.plus.version}</version>
             </dependency>
             <dependency>
                 <groupId>com.baomidou</groupId>
                 <artifactId>mybatis-plus-extension</artifactId>
                 <version>${mybatis.plus.version}</version>
             </dependency>
             <dependency>
                 <groupId>com.baomidou</groupId>
                 <artifactId>mybatis-plus-generator</artifactId>
                 <version>${mybatis.plus.version}</version>
             </dependency>
             <dependency>
                 <groupId>com.github.pagehelper</groupId>
                 <artifactId>pagehelper-spring-boot-starter</artifactId>
                 <version>${pagehelper.starter.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.springframework.cloud</groupId>
                 <artifactId>spring-cloud-dependencies</artifactId>
                 <version>${spring-cloud.version}</version>
                 <scope>import</scope>
                 <type>pom</type>
             </dependency>
             <dependency>
                 <groupId>com.alibaba.cloud</groupId
               <artifactId>spring-cloud-alibaba-dependencies</artifactId
               <version>${spring-cloud-alibaba.version}</version
               <type>pom</type
               <scope>import</scope
           </dependency
           <dependency
               <groupId>org.springframework.security</groupId
               <artifactId>spring-security-jwt</artifactId
               <version>${spring-security-jwt.version}</version
           </dependency
       </dependencies
   </dependencyManagement
</project>

  (2)创建子项目knows-resource,设置Group、Artifict、Java Version、记得Package加.、选择SpringBoot最低版本2.4.10,什么都不勾选,对knows-resource项目的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>
     <parent>
         <groupId>cn.tedu</groupId>
         <artifactId>knows</artifactId>
         <version>0.0.1-SNAPSHOT</version>
         <relativePath/> <!-- lookup parent from repository -->
     </parent>
     <groupId>cn.tedu</groupId>
     <artifactId>knows-resource</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <name>knows-resource</name>
     <description>Demo project for Spring Boot</description>
 
     <dependencies>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
         <!-- springCloudAlibaba 注册到nacos的依赖 -->
         <dependency>
             <groupId>com.alibaba.cloud</groupId>
             <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
         </dependency>
     </dependencies>
 </project>

在knows-resource项目的application-properties添加配置信息:

 # 静态资源访问端口
 server.port=8899
 
 # 修改当前项目的静态资源默认路径
 spring.resources.static-locations=file:F:/upload
 
 # 微服务必须有一个项目名称,这个名称用于注册到nacos
 spring.application.name=resource-server
 
 # 指定要注册的nacos的位置, 默认值是localhost:8848,如果就是这个值可以不写
 spring.cloud.nacos.discovery.server-addr=localhost:8848

最后在SpringBoot启动类上添加一个注解,完成注册:

 @SpringBootApplication
 // 下面注解表示当前项目启动时要注册到注册中心!
 @EnableDiscoveryClient
 public class KnowsResourceApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(KnowsResourceApplication.class, args);
    }
 
 }

我们可以将配置过程划分为3个步骤:

  1. pom.xml依赖的配置

  1. application.properties的配置

  1. SpringBoot启动类的配置

  很多框架和组件都是需要配置这3个位置的,为了大家方便记忆,我们称之为“配置三板斧”。

  先启动nacos,再启动knows-resource项目,就可以在nacos的服务管理的服务列表中看到注册到nacos注册中心的微服务项目了。

 

2 Spring Gateway网关

2.1 网关的基本概念

  所谓网关就是负责对外界客户端请求当前项目时,进行统一管理的组件,网关就是所有请求进入项目前必须经过的关口。

这个关口有如下作用或操作:

  • 身份验证与权限控制

  • 监视监控与记录

  • 根据请求路径动态路由到不同服务器

网关在项目中的位置如图: 

2.2 创建网关项目

  我们下面就要创建网关项目,最终实现通过浏览器访问网关的路径,获得静态资源服务器的内容。

  SpringCloud提供了实现网关的框架,我们使用的是Spring提供的Spring-Gateway,这个组件性能良好,可以支持高并发、高可用、高性能的互联网应用程序的要求。

在父项目knows的基础上新建module子项目:gateway

  (1)选择Spring Initializr

  (2)修改Group、Artifict、Java Version

  (3)选择Spring Cloud Routing--->Gateway,boot版本选择最低版本:2.4.10

  之后选择默认,点击Finish,等待加载完毕即可。

父子相认:三板斧

(1)父项目pom.xml添加子module

 <modules>
     <module>knows-resource</module>
     <module>gateway</module>
 </modules>

子项目gateway模块的pom.xml修改、添加依赖

 <?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>
     <parent>
         <groupId>cn.tedu</groupId>
         <artifactId>knows</artifactId>
         <version>0.0.1-SNAPSHOT</version>
         <relativePath/> <!-- lookup parent from repository -->
     </parent>
     <groupId>cn.tedu</groupId>
     <artifactId>gateway</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <name>gateway</name>
     <description>Demo project for Spring Boot</description>
 
     <dependencies>
         <!--
  下面的依赖就是网关的依赖
             这个网关的依赖自带了启动项目的功能,
             注意:这个依赖和spring-boot-starter-web冲突,不能共存
          -->
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-gateway</artifactId>
         </dependency>
         
         <!--注册到nacos的依赖-->
         <dependency>
             <groupId>com.alibaba.cloud</groupId>
             <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
         </dependency>
     </dependencies>
 </project>

(2)配置application.properties

  我们可以使用application.properties文件进行配置工作,但是application的配置比较繁琐有冗余。因为网关配置比较复杂,所以推荐使用yaml(yml)格式的配置文件。我们在gateway项目的resources文件夹下创建一个名为application.yml的文件,这个文件和application.properties文件一样,会在SpringBoot启动时自动解析(yml比properties先解析,内容相同时,properties会覆盖yml的内容)。

代码如下:

 server:
  port: 9000
 spring:
  application:
    name: gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          enabled: true  #是否与服务注册与发现组件结合,通过 serviceId 转发到具体的服务
          lower-case-service-id: true # 忽略大小写服务器名称
      routes:  # 开始路由配置
        - id: gateway-resource #路由配置的名称和具体服务无关
           # resource-server路由的服务器的名称
           # lb: 是 Load Balance(负载均衡)的缩写
          uri: lb://resource-server  # 必须和微服务项目名称一致
           # 路由的路径设置
           # 表示如果访问localhost:9000/image/xxxxxxx
           # 那么就相当于访问resource-server服务中的内容了!
          predicates:
            - Path=/image/**  # 路由特征

补充:

  • yml

  properties文件的冗余(缺点),下面是使用properties配置的数据连接池:

 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
 spring.datasource.url=jdbc:mysql://localhost:3306/knows?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
 spring.datasource.username=root
 spring.datasource.password=root

  上面spring.datasource反复出现多次,如果一个配置文件有大量配置,这样的重复是数不胜数的,我们可以使用另外格式的配置文件:application.yml(全称yaml)

 spring:
  datasource:
  driver-class-name:com.mysql.cj.jdbc.Driver
  url:jdbc:mysql://localhost:3306/knows?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
  username:root
  password:root
  • 负载均衡:

    如果一个业务有多个服务器提供服务,那么可能会产生每个服务器压力不均衡的情况,负载均衡技术能够通过已经编写好的算法将当前提供服务的服务器的压力尽量保持在同一个水平。

(3)SpringBoot启动类添加注解@EnableDiscoveryClient,注册到nacos

 @SpringBootApplication
 // 网关也要注册到nacos
 @EnableDiscoveryClient
 public class GatewayApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(GatewayApplication.class, args);
    }
 
 }

2.3 通过路由特征访问静态资源

  我们在网关的设置中设置了路由特征:/image/**就是我们设置的路由特征,意思是localhost:9000/image/ * *的请求都会被分配到resource-server服务器

    具体来说 localhost:9000/image/a.jpg

    会访问的实际路径为 localhost:8899/image/a.jpg

  但是当前这个路径没有资源,会报错,我们要设置8899/image/为服务器的根目录,以匹配路由特征,到knows-resource项目中的application.properties文件中添加一个配置即可:

 # 默认情况下 localhost:8899/a.jpg就可以访问资源路径下的文件了
 # 添加这个配置后,要求当前项目资源的访问路径统一添加/image为前缀
 # 简单来说,之前localhost:8899/a.jpg的路径变为了localhost:8899/image/a.jpg
 server.servlet.context-path=/image

  重启knows-resource项目,输入路径测试:http://localhost:8899/image/a.jpg,观察是否能访问资源(要保证资源路径下真的有a.jpg这个图片),能访问资源说明路径设置成功!

  下面再启动gateway,输入路径测试网关是否生效:http://localhost:9000/image/a.jpg。网关注册成功后nacos列表页面:

  如果上面的路径能够正常访问图片的资源的话,一切正常。

Spring-Gateway的依赖和Spring-MVC的依赖是冲突的:

  Spring-Gateway自带了Netty服务器,Spring-MVC自带Tomcat服务器

设置网关后,可以访问多个资源服务期内的资源:

 

3 前后端分离

3.1 什么是前后端分离?

  所谓前后端分离就是java项目中完全不包含任何html \ js \ css \ 资源图片等静态资源文件前端项目不包含任何java代码(包括控制层代码 \ 业务逻辑层代码 \ 数据访问层代码),现今流行的前端项目是vue+node.js

这么做的好处:

  1. 前后端变化互不影响

  1. 后端可以在网关的帮助下为各种前端类型做出响应

3.2 创建前端项目

  由于我们技术条件限制,仍然使用SpringBoot项目来模拟一个前端项目效果。

创建前端项目knows-client:

(1)选择Spring Initializr

(2)修改Group、Artifict、Java Version、Package加.

(3)选择Web,点击SpringWeb,boot版本选择最低版本:2.4.10

(4)父子相认:父项目添加子项目的module

 <module>knows-client</module>

子项目knows-client的pom.xml进行修改:

 <?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>
     <parent>
         <groupId>cn.tedu</groupId>
         <artifactId>knows</artifactId>
         <version>0.0.1-SNAPSHOT</version>
         <relativePath/> <!-- lookup parent from repository -->
     </parent>
     <groupId>cn.tedu</groupId>
     <artifactId>knows-client</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <name>knows-client</name>
     <description>Demo project for Spring Boot</description>
 
     <dependencies>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
     </dependencies>
 
 </project>

  将portal项目中的所有static文件夹下的静态资源复制到knows-client项目的static文件夹下,启动client项目,访问页面可以正常显示表示当前客户端运行正常。

  以访问注册页面为例:

 

3.3 创建用户管理模块knows-sys

  我们当前项目已经有了注册中心、网关、前端等必要项目的支持,我们最终的目标是将portal项目中的功能从单体项目中抽取出来迁移到用户管理模块和问答模块中。首先我们的小目标是将注册功能迁移出来,所以先创建用户管理模块:knows-sys

(1)在父项目knows上右键new Module,选择Spring Initializr

(2)修改Group、Artifict、Java Version、Package加.

(3)什么都不勾选

(4)点击Finish完成项目创建

(5)父项目knows中进行父子相认,添加子类module

 <module>knows-sys</module>

(6)子项目依赖较多,可以直接参考使用(直接复制粘贴)

 <?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>
     <parent>
         <groupId>cn.tedu</groupId>
         <artifactId>knows</artifactId>
         <version>0.0.1-SNAPSHOT</version>
         <relativePath/> <!-- lookup parent from repository -->
     </parent>
     <groupId>cn.tedu</groupId>
     <artifactId>knows-sys</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <name>knows-sys</name>
     <description>Demo project for Spring Boot</description>
 
     <dependencies>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
         <dependency>
             <groupId>com.alibaba.cloud</groupId>
             <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
         </dependency>
         <!--       <dependency>-->
         <!--           <groupId>cn.tedu</groupId>-->
         <!--           <artifactId>knows-commons</artifactId>-->
         <!--       </dependency>-->
         <dependency>
             <groupId>com.baomidou</groupId>
             <artifactId>mybatis-plus-boot-starter</artifactId>
         </dependency>
         <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
         </dependency>
         <!-- nacos配置中心的依赖 -->
         <dependency>
             <groupId>com.alibaba.cloud</groupId>
             <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
         </dependency>
         <!-- 验证框架 -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-validation</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-security</artifactId>
         </dependency>
     </dependencies>
 </project>

   刷新Maven!

 

posted @ 2021-09-07 22:24  Coder_Cui  阅读(701)  评论(0编辑  收藏  举报