第二章 广告系统骨架开发

此博客用于个人学习,来源于网上,对知识点进行一个整理。

1. 广告系统主工程:

创建 project:imooc-ad-spring-cloud,采用 maven 工程的方式创建。

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.imooc.ad</groupId>
    <artifactId>imooc-ad</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <name>imooc-ad-spring-cloud</name>
    <description>Project For Imooc Ad SpringCloud</description>

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

    <!--自定义元素,管理通用属性-->
    <properties>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.18</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </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>

    <!--远程仓库-->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>

2. Eureka Server:

在 imooc-ad-spring-cloud 下,创建 module:ad-eureka。

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <!-- 指定父pom, 在父pom中配置子模块的公共依赖 -->
    <parent>
        <artifactId>imooc-ad</artifactId>
        <groupId>com.imooc.ad</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <!-- 当前项目/模块的坐标, groupId从父模块中继承 -->
    <artifactId>ad-eureka</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <!-- 模块名及描述信息 -->
    <name>ad-eureka</name>
    <description>Spring Cloud Eureka</description>

    <!-- eureka server: 提供服务发现与服务注册 -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

    <!--
        SpringBoot的Maven插件, 能够以Maven的方式为应用提供SpringBoot的支持,可以将
        SpringBoot应用打包为可执行的jar或war文件, 然后以通常的方式运行SpringBoot应用
     -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2.1 启动类:

@EnableEurekaServer
@SpringBootApplication
public class EurekaAppliction {

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

2.2 单节点部署:

先部署单节点的情况,后面再进行多节点的部署。

application.yml:

spring:
 application:
   name: ad-eureka

server:
  port: 8000

eureka:
  instance:
    hostname: localhost
  client: # 单节点设置为 false
    fetch-registry: false
    register-with-eureka: false
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

2.3 多节点部署:

进行多节点的部署,分别为 server1,server2,server3,对应端口 8000-8002。

改造 yml 文件:

---
spring:
  application:
    name: ad-eureka
  profiles: server1
server:
  port: 8000
eureka:
  instance:
    hostname: server1
    prefer-ip-address: false
  client:
    service-url:
      defaultZone: http://server2:8001/eureka/,http://server3:8002/eureka/

---
spring:
  application:
    name: ad-eureka
  profiles: server2
server:
  port: 8001
eureka:
  instance:
    hostname: server2
    prefer-ip-address: false
  client:
    service-url:
      defaultZone: http://server1:8000/eureka/,http://server3:8002/eureka/

---
spring:
  application:
    name: ad-eureka
  profiles: server3
server:
  port: 8002
eureka:
  instance:
    hostname: server3
    prefer-ip-address: false
  client:
    service-url:
      defaultZone: http://server1:8000/eureka/,http://server2:8001/eureka/

注意:在部署多节点的时候,需要对前面单节点部署的代码进行注释,避免由于优先加载前面部分代码导致的错误。

3. 微服务架构及网关组件介绍:

微服务,似乎也是服务,都是对系统进行拆分。因此两者非常容易混淆,但其实却有一些差别:

微服务的特点:

  • 单一职责:微服务中每一个服务都对应唯一的业务能力,做到单一职责。
  • 微:微服务的服务拆分粒度很小,例如一个用户管理就可以作为一个服务。每个服务虽小,但“五脏俱全”。
  • 面向服务:面向服务是说每个服务都要对外暴露 Rest 风格服务接口 API。并不关心服务的技术实现,做到与平台和语言无关,也不限定用什么技术实现,只要提供 Rest 的接口即可。
  • 自治:自治是说服务间互相独立,互不干扰。
  • 团队独立:每个服务都是一个独立的开发团队,人数不能过多。
  • 技术独立:因为是面向服务,提供 Rest 接口,使用什么技术没有别人干涉。
  • 前后端分离:采用前后端分离开发,提供统一 Rest 接口,后端不用再为 PC、移动段开发不同接口。
  • 数据库分离:每个服务都使用自己的数据源。
  • 部署独立,服务间虽然有调用,但要做到服务重启不影响其它服务。有利于持续集成和持续交付。每个服务都是独立的组件,可复用,可替换,降低耦合,易维护。

在这里插入图片描述

这里只是对微服务讲一个大概,更多更具体的建议看下面两篇博客:

SpringCloud 基本使用

详解微服务架构

3.1 微服务架构的两种方式:

  1. 点对点模式:服务之间直接调用,每个微服务都开放 Rest API,并调用其他微服务的接口。

在这里插入图片描述

  1. API-网关方式:业务接口通过 API 网关暴露,是所有客户端接口的唯一入口,微服务之间的通信也是通过 API 网关。

在这里插入图片描述

3.2 Zuul 的生命周期:

服务网关是微服务架构中一个不可或缺的部分。通过服务网关统一向外系统提供 REST API 的过程中,除了具备服务路由、均衡负载功能之外,它还具备了权限控制等功能。Spring Cloud Netflix 中的 Zuul 就担任了这样的一个角色,为微服务架构提供了前门保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,使得服务集群主体能够具备更高的可复用性和可测试性。

这张是 Zuul 官网提供的请求生命周期图,清晰的表现了一个请求在各个过滤器的执行顺序。

在这里插入图片描述

正常流程:

  • 请求到达首先会经过 pre 类型过滤器,而后到达 route 类型,进行路由,请求就到达真正的服务提供者,执行请求,返回结果后,会到达 post 过滤器。而后返回响应。

异常流程:

  • 整个过程中,pre 或者 route 过滤器出现异常,都会直接进入 error 过滤器,在 error 处理完毕后,会将请求交给 POST 过滤器,最后返回给用户。
  • 如果是 error 过滤器自己出现异常,最终也会进入 POST 过滤器,将最终结果返回给请求客户端。
  • 如果是 POST 过滤器出现异常,会跳转到 error 过滤器,但是与 pre 和 route 不同的是,请求不会再到达 POST 过滤器了。

4. Gateway-server:

4.1 基础配置:

在 imooc-ad-spring-cloud 下,创建 module:ad-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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>imooc-ad</artifactId>
        <groupId>com.imooc.ad</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <!-- 当前项目/模块的坐标, groupId从父模块中继承 -->
    <artifactId>ad-gateway</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <!-- 模块名及描述信息 -->
    <name>ad-gateway</name>
    <description>ad-gateway</description>

    <dependencies>
        <!--
            Eureka 客户端, 客户端向 Eureka Server 注册的时候会提供一系列的元数据信息, 例如: 主机, 端口, 健康检查url等
            Eureka Server 接受每个客户端发送的心跳信息, 如果在某个配置的超时时间内未接收到心跳信息, 实例会被从注册列表中移除
        -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!-- 服务网关 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
    </dependencies>

    <!--
        SpringBoot的Maven插件, 能够以Maven的方式为应用提供SpringBoot的支持,可以将
        SpringBoot应用打包为可执行的jar或war文件, 然后以通常的方式运行SpringBoot应用
     -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

启动类:

@EnableZuulProxy
@SpringCloudApplication
public class ZuulGatewayApplication {

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

application.yml:

server:
  port: 9000
spring:
  application:
    name: ad-gateway
eureka:
  client:
    service-url:
      defaultZone: http://server1:8000/eureka/

4.2 自定义网关过滤器:

接下来,实现网关中最核心的概念——过滤器,用于日志的操作。

过滤器1:PreRequestFilter

//将过滤器注册到容器中
@Slf4j
@Component
public class PreRequestFilter extends ZuulFilter {
    //filter执行类型
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    //filter执行顺序
    @Override
    public int filterOrder() {
        return 0;
    }

    //是否需要执行过滤器
    @Override
    public boolean shouldFilter() {
        return true;
    }

    //具体操作,记录该操作的起始时间戳
    @Override
    public Object run() throws ZuulException {

        RequestContext ctx = RequestContext.getCurrentContext();
        ctx.set("startTime",System.currentTimeMillis());
        return null;
    }
}

过滤器2:AccessLogFilter

@Slf4j
@Component
public class AccessLogFilter extends ZuulFilter {
    //filter执行类型
    @Override
    public String filterType() {
        return FilterConstants.POST_TYPE;
    }

    //filter执行顺序
    @Override
    public int filterOrder() {
        return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 1;
    }

    //是否需要执行过滤器
    @Override
    public boolean shouldFilter() {
        return true;
    }

    //具体操作:日志记录操作的执行时间和路径
    @Override
    public Object run() throws ZuulException {

        RequestContext context = RequestContext.getCurrentContext();
        HttpServletRequest request = context.getRequest();
        long startTime = (Long) context.get("startTime");
        //请求路径
        String uri = request.getRequestURI();
        //请求时间
        long duration = System.currentTimeMillis() - startTime;

        Logger log = null;
        assert false;
        log.info("uri: " + uri + ", duration: " + duration / 100 + "ms");

        return null;
    }
}

这样的话,整个广告系统的骨架就开发完成了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值