《基于SpringCloud微服务架构广告系统设计与实现》笔记

1-1 课程导学

什么是广告系统?

 

 2-1 广告系统概览

 

 

 

 

 2-2 广告系统架构

 

 

 2-3 准备工作与系统目录结构

 

 

2-3 准备工作与系统目录结构

 

第3章 广告系统骨架开发

3-1 Maven基础知识

 

 

 

3-2 Maven 相关特性

 

 

3-3 广告系统主工程

...建立项目结构...

 Maven有三种类型的仓库:

本地仓库:工程里依赖的jar包,maven会主动下载到本地目录的.m2。

中央仓库:由maven社区提供,包含有大量的常用库。

远程仓库:对开发者提供的,开发者把自己编写的包放在这个仓库,工程就可以指定远程仓库去下载。

 

3-4 单节点 Eureka Server 的开发

 

3-5 Eureka Server 的部署

分别启动单节点和多节点的Eureka Server

单节点配置文件:

多节点(三个节点的Eureka server):

由于父工程会管理所有子工程,因此在父工程打包:

启动第一个服务:

类似的,分别启动server2和3。

 

3-6 微服务架构及网关组件介绍

三种类型的过滤器可以分别用来实现不同的功能。

Pre filters:请求被路由之前调用,可以利用这种过滤器实现身份认证、在集群中选择请求的微服务记录调试信息等等。

Routing filters:这种过滤器将请求路由到微服务,即用于构造发送给微服务的请求。使用Apache的HttpClient或者Netflix的Ribbon请求微服务。

Post filters:这种过滤器在路由到微服务以后执行,可以为响应添加Http的header、收集统计信息和指标、将响应从微服务发送给客户端等等。

Error filters:当请求发生了错误去执行的过滤器。

Custom filters:自定义的过滤器。例如我们可以定义一种静态类型的过滤器,直接在Zuul中响应,而不在微服务中响应。如果请求的是一个静态文件,可以不需要经过路由到微服务,直接在Custom filters返回给客户端。

 

3-7 网关启动程序的开发

 

3-8 自定义网关过滤器的开发

 实现两个自定义过滤器完成一个访问日志的功能。

 PreRequestFilter.java

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class PreRequestFilter extends ZuulFilter {

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

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

AccessLogFilter.java

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Slf4j
@Component
public class AccessLogFilter extends ZuulFilter {

    @Override
    public String filterType() {
        return FilterConstants.POST_TYPE;
    }

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

        log.info("uri: " + uri + ", duration: " + duration / 100 + "ms");

        return null;
    }
}

 

第4章 微服务通用模块开发

4-1 关于通用模块功能的介绍

4-2 统一响应处理的开发

CommonResponseDataAdvice.java

import com.imooc.ad.annotation.IgnoreResponseAdvice;
import com.imooc.ad.vo.CommonResponse;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

@RestControllerAdvice
public class CommonResponseDataAdvice implements ResponseBodyAdvice<Object> {

    @Override
    @SuppressWarnings("all")
    public boolean supports(MethodParameter methodParameter,
                            Class<? extends HttpMessageConverter<?>> aClass) {

        if (methodParameter.getDeclaringClass().isAnnotationPresent(
                IgnoreResponseAdvice.class
        )) {
            return false;
        }

        if (methodParameter.getMethod().isAnnotationPresent(
                IgnoreResponseAdvice.class
        )) {
            return false;
        }

        return true;
    }

    @Nullable
    @Override
    @SuppressWarnings("all")
    public Object beforeBodyWrite(@Nullable Object o,
                                  MethodParameter methodParameter,
                                  MediaType mediaType,
                                  Class<? extends HttpMessageConverter<?>> aClass,
                                  ServerHttpRequest serverHttpRequest,
                                  ServerHttpResponse serverHttpResponse) {

        CommonResponse<Object> response = new CommonResponse<>(0, "");
        if (null == o) {
            return response;
        } else if (o instanceof CommonResponse) {
            response = (CommonResponse<Object>) o;
        } else {
            response.setData(o);
        }

        return response;
    }
}

4-3 统一异常处理的开发

自定义AdException类。

GlobalExceptionAdvice.java

 

import com.imooc.ad.exception.AdException;
import com.imooc.ad.vo.CommonResponse;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;

@RestControllerAdvice
public class GlobalExceptionAdvice {

    @ExceptionHandler(value = AdException.class)
    public CommonResponse<String> handlerAdException(HttpServletRequest req,
                                                     AdException ex) {
        CommonResponse<String> response = new CommonResponse<>(-1,
                "business error");
        response.setData(ex.getMessage());
        return response;
    }
}

 

4-4 统一配置的开发

定义http消息转换器(将Java对象转换为http的输出流)。

WebConfiguration.java

import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>>
                                                       converters) {

        converters.clear();
        converters.add(new MappingJackson2HttpMessageConverter());
    }
}

 

 第5章 广告投放系统的开发

 5-1 Spring IOC和MVC基础知识

 

 

 

 5-2 SpringBoot 常用功能特性介绍

 

 启动的方法还有两种:

 

 

定时任务:

 

 5-3 广告投放系统数据表设计

 

 

 

第7章 广告检索系统 - 广告数据索引的设计与实现

7-1 广告数据索引设计介绍

 

 

 7-2 广告数据索引维护介绍

 

 

 

 

 7-3 推广计划索引对象定义与服务实现

IndexAware.java

package com.imooc.ad.index;

public interface IndexAware<K, V> {

    V get(K key);

    void add(K key, V value);

    void update(K key, V value);

    void delete(K key, V value);
}

索引对象 AdPlanObject.java

package com.imooc.ad.index.adplan;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class AdPlanObject {

    private Long planId;
    private Long userId;
    private Integer planStatus;
    private Date startDate;
    private Date endDate;

    public void update(AdPlanObject newObject) {

        if (null != newObject.getPlanId()) {
            this.planId = newObject.getPlanId();
        }
        if (null != newObject.getUserId()) {
            this.userId = newObject.getUserId();
        }
        if (null != newObject.getPlanStatus()) {
            this.planStatus = newObject.getPlanStatus();
        }
        if (null != newObject.getStartDate()) {
            this.startDate = newObject.getStartDate();
        }
        if (null != newObject.getEndDate()) {
            this.endDate = newObject.getEndDate();
        }
    }
}

 

posted @ 2019-05-14 11:40  Z.Y.X  阅读(1649)  评论(0编辑  收藏  举报