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