├── .gitignore
├── Spring cloud 实现广告系统.pdf
├── kafka-demo
├── pom.xml
└── src
│ └── main
│ └── java
│ └── com
│ └── sxzhongf
│ └── kafkademo
│ ├── CustomKafkaPartitioner.java
│ ├── KafkaDemoConsumer.java
│ ├── KafkaDemoProducer.java
│ ├── KafkaKeyCategory.java
│ └── ProducerDemoCallback.java
├── mscx-ad-common
├── pom.xml
└── src
│ └── main
│ └── java
│ └── com
│ └── sxzhongf
│ └── ad
│ └── common
│ ├── advice
│ ├── CommonRequestAdvice.java
│ ├── CommonResponseDataAdvice.java
│ └── GlobalExceptionAdvice.java
│ ├── annotation
│ └── IgnoreResponseAdvice.java
│ ├── config
│ └── WebConfiguration.java
│ ├── exception
│ └── AdException.java
│ ├── export
│ ├── FileConstant.java
│ └── table
│ │ ├── AdCreativeRelationUnitTable.java
│ │ ├── AdCreativeTable.java
│ │ ├── AdPlanTable.java
│ │ ├── AdUnitDistrictTable.java
│ │ ├── AdUnitHobbyTable.java
│ │ ├── AdUnitKeywordTable.java
│ │ └── AdUnitTable.java
│ ├── utils
│ └── CommonUtils.java
│ └── vo
│ └── CommonResponse.java
├── mscx-ad-dashboard
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── sxzhongf
│ │ └── ad
│ │ └── AdDashboardApplication.java
│ └── resources
│ └── application.yml
├── mscx-ad-db
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── sxzhongf
│ │ │ └── ad
│ │ │ ├── DBExportApplication.java
│ │ │ └── service
│ │ │ ├── IExportDataService.java
│ │ │ ├── controller
│ │ │ └── ExportDataController.java
│ │ │ └── impl
│ │ │ └── ExportDataServiceImpl.java
│ └── resources
│ │ ├── application.yml
│ │ └── db
│ │ ├── init-data.sql
│ │ └── migration
│ │ └── V1__CREATE_NEW_DATABASE_AD.sql
│ └── test
│ └── java
│ └── TestTable.java
├── mscx-ad-discovery
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── sxzhongf
│ │ └── ad
│ │ └── discovery
│ │ └── DiscoveryApplication.java
│ └── resources
│ └── application.yml
├── mscx-ad-feign-sdk
├── pom.xml
└── src
│ └── main
│ └── java
│ └── com
│ └── sxzhongf
│ └── ad
│ └── feign
│ └── client
│ ├── ISponsorFeignClient.java
│ ├── SponsorClientHystrix.java
│ └── vo
│ ├── AdPlanGetRequestVO.java
│ └── AdPlanVO.java
├── mscx-ad-gateway
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── sxzhongf
│ │ └── ad
│ │ └── gateway
│ │ ├── GatewayApplication.java
│ │ ├── filter
│ │ ├── AccessLogFilter.java
│ │ ├── CORSFilter.java
│ │ └── TokenFilter.java
│ │ └── route
│ │ └── GatewayRoutes.java
│ └── resources
│ └── application.yml
├── mscx-ad-search
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── sxzhongf
│ │ │ └── ad
│ │ │ ├── AdSearchApplication.java
│ │ │ ├── client
│ │ │ ├── ISponsorFeignClient.java
│ │ │ ├── SponsorClientHystrix.java
│ │ │ └── vo
│ │ │ │ ├── AdPlanGetRequestVO.java
│ │ │ │ └── AdPlanVO.java
│ │ │ ├── config
│ │ │ └── BinlogConfig.java
│ │ │ ├── controller
│ │ │ ├── SearchController.java
│ │ │ └── SearchFeignController.java
│ │ │ ├── handler
│ │ │ └── AdLevelDataHandler.java
│ │ │ ├── index
│ │ │ ├── AdDataLevel.java
│ │ │ ├── CommonStatus.java
│ │ │ ├── IIndexAware.java
│ │ │ ├── IndexDataTableUtils.java
│ │ │ ├── IndexFileLoader.java
│ │ │ ├── adplan
│ │ │ │ ├── AdPlanIndexAwareImpl.java
│ │ │ │ └── AdPlanIndexObject.java
│ │ │ ├── adunit
│ │ │ │ ├── AdUnitConstants.java
│ │ │ │ ├── AdUnitIndexAwareImpl.java
│ │ │ │ └── AdUnitIndexObject.java
│ │ │ ├── creative
│ │ │ │ ├── CreativeIndexAwareImpl.java
│ │ │ │ └── CreativeIndexObject.java
│ │ │ ├── creative_relation_unit
│ │ │ │ ├── CreativeRelationUnitIndexAwareImpl.java
│ │ │ │ └── CreativeRelationUnitIndexObject.java
│ │ │ ├── district
│ │ │ │ ├── UnitDistrictIndexAwareImpl.java
│ │ │ │ └── UnitDistrictIndexObject.java
│ │ │ ├── hobby
│ │ │ │ ├── UnitHobbyIndexAwareImpl.java
│ │ │ │ └── UnitHobbyIndexObject.java
│ │ │ └── keyword
│ │ │ │ ├── UnitKeywordIndexAwareImpl.java
│ │ │ │ └── UnitKeywordIndexObject.java
│ │ │ ├── mysql
│ │ │ ├── CustomBinlogClient.java
│ │ │ ├── TemplateHolder.java
│ │ │ ├── constant
│ │ │ │ ├── Constant.java
│ │ │ │ └── OperationTypeEnum.java
│ │ │ ├── dto
│ │ │ │ ├── BinlogRowData.java
│ │ │ │ ├── BinlogTemplate.java
│ │ │ │ ├── JsonTable.java
│ │ │ │ ├── MysqlRowData.java
│ │ │ │ ├── ParseCustomTemplate.java
│ │ │ │ └── TableTemplate.java
│ │ │ └── listener
│ │ │ │ ├── AggregationListener.java
│ │ │ │ ├── Ilistener.java
│ │ │ │ └── IncrementListener.java
│ │ │ ├── runner
│ │ │ └── BinlogRunner.java
│ │ │ ├── search
│ │ │ ├── ISearch.java
│ │ │ ├── SearchImpl.java
│ │ │ └── vo
│ │ │ │ ├── SearchRequest.java
│ │ │ │ ├── SearchResponse.java
│ │ │ │ ├── feature
│ │ │ │ ├── DistrictFeature.java
│ │ │ │ ├── FeatureRelation.java
│ │ │ │ ├── HobbyFeatrue.java
│ │ │ │ └── KeywordFeature.java
│ │ │ │ └── media
│ │ │ │ ├── AdSlot.java
│ │ │ │ ├── App.java
│ │ │ │ ├── Device.java
│ │ │ │ └── Geo.java
│ │ │ ├── sender
│ │ │ ├── ISender.java
│ │ │ ├── index
│ │ │ │ └── IndexSender.java
│ │ │ └── kafka
│ │ │ │ └── KafkaSender.java
│ │ │ ├── service
│ │ │ └── BinlogServiceTest.java
│ │ │ └── utils
│ │ │ └── CommonUtils.java
│ └── resources
│ │ ├── MySQL BinLog.md
│ │ ├── application.yml
│ │ ├── index-note.md
│ │ └── template.json
│ └── test
│ ├── java
│ └── com
│ │ └── sxzhongf
│ │ └── ad
│ │ ├── AdSearchApplication.java
│ │ └── search
│ │ └── SearchTest.java
│ └── resources
│ └── application.yml
├── mscx-ad-sponsor
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── sxzhongf
│ │ │ └── ad
│ │ │ ├── SponsorApplication.java
│ │ │ ├── client
│ │ │ └── vo
│ │ │ │ ├── CreativeRequestVO.java
│ │ │ │ ├── CreativeResponseVO.java
│ │ │ │ ├── CreativeUnitRelationshipRequestVO.java
│ │ │ │ ├── CreativeUnitRelationshipResponseVO.java
│ │ │ │ ├── PlanGetRequestVO.java
│ │ │ │ ├── PlanRequestVO.java
│ │ │ │ ├── PlanResponseVO.java
│ │ │ │ ├── UnitDistrictRequestVO.java
│ │ │ │ ├── UnitDistrictResponseVO.java
│ │ │ │ ├── UnitHobbyRequestVO.java
│ │ │ │ ├── UnitHobbyResponseVO.java
│ │ │ │ ├── UnitKeywordRequestVO.java
│ │ │ │ ├── UnitKeywordResponseVO.java
│ │ │ │ ├── UnitRequestVO.java
│ │ │ │ ├── UnitResponseVO.java
│ │ │ │ ├── UserRequestVO.java
│ │ │ │ └── UserResponseVO.java
│ │ │ ├── constant
│ │ │ ├── CommonStatus.java
│ │ │ ├── Constants.java
│ │ │ ├── CreativeMaterielType.java
│ │ │ └── CreativeType.java
│ │ │ ├── controller
│ │ │ ├── CreativeController.java
│ │ │ ├── PlanController.java
│ │ │ ├── UnitController.java
│ │ │ └── UserController.java
│ │ │ ├── dao
│ │ │ ├── AdPlanRepository.java
│ │ │ ├── AdUnitRepository.java
│ │ │ ├── AdUserRepository.java
│ │ │ ├── CreativeRepository.java
│ │ │ └── unit_condition
│ │ │ │ ├── AdUnitDistrictRepository.java
│ │ │ │ ├── AdUnitHobbyRepository.java
│ │ │ │ ├── AdUnitKeywordRepository.java
│ │ │ │ └── RelationshipCreativeUnitRepository.java
│ │ │ ├── entity
│ │ │ ├── AdCreative.java
│ │ │ ├── AdPlan.java
│ │ │ ├── AdUnit.java
│ │ │ ├── AdUser.java
│ │ │ └── unit_condition
│ │ │ │ ├── AdUnitDistrict.java
│ │ │ │ ├── AdUnitHobby.java
│ │ │ │ ├── AdUnitKeyword.java
│ │ │ │ └── RelationshipCreativeUnit.java
│ │ │ └── service
│ │ │ ├── ICreativeService.java
│ │ │ ├── IPlanService.java
│ │ │ ├── IUnitService.java
│ │ │ ├── IUserService.java
│ │ │ └── impl
│ │ │ ├── CreativeServiceImpl.java
│ │ │ ├── PlanServiceImpl.java
│ │ │ ├── UnitServiceImpl.java
│ │ │ └── UserServiceImpl.java
│ └── resources
│ │ └── application.yml
│ └── test
│ └── java
│ └── com
│ └── sxzhongf
│ └── ad
│ ├── SponsorApplication.java
│ └── service
│ ├── AdPlanServiceTest.java
│ ├── AdUnitServiceTest.java
│ └── UserServiceTest.java
├── mscx-ad-zuul
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── sxzhongf
│ │ └── ad
│ │ └── gateway
│ │ ├── GatewayApplication.java
│ │ └── filter
│ │ ├── AccessLogFilter.java
│ │ ├── PreRequestFilter.java
│ │ └── ValidateTokenFilter.java
│ └── resources
│ └── application.yml
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.war
15 | *.ear
16 | *.zip
17 | *.tar.gz
18 | *.rar
19 |
20 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
21 | hs_err_pid*
22 |
23 | # eclipse ignore
24 | .settings/
25 | .project
26 | .classpath
27 |
28 | # idea ignore
29 | .idea/
30 | *.ipr
31 | *.iml
32 | *.iws
33 | target
34 |
35 | # temp ignore
36 | *.log
37 | *.cache
38 | *.diff
39 | *.patch
40 | *.tmp
41 |
42 | # system ignore
43 | .DS_Store
44 | Thumbs.db
45 |
46 | # others
47 | .extract
48 |
--------------------------------------------------------------------------------
/Spring cloud 实现广告系统.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Isaac-Zhang/mscx-ad/2b4d3504be79589dadbbd1b975e1128e41445010/Spring cloud 实现广告系统.pdf
--------------------------------------------------------------------------------
/kafka-demo/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | 4.0.0
7 |
8 | com.sxzhongf
9 | kafka-demo
10 | 1.0-SNAPSHOT
11 |
12 |
13 |
14 | org.apache.kafka
15 | kafka_2.11
16 | 2.3.0
17 |
18 |
19 |
20 |
21 |
22 |
23 | org.apache.maven.plugins
24 | maven-compiler-plugin
25 | 3.7.0
26 |
27 | 1.8
28 | 1.8
29 | UTF-8
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/kafka-demo/src/main/java/com/sxzhongf/kafkademo/CustomKafkaPartitioner.java:
--------------------------------------------------------------------------------
1 | package com.sxzhongf.kafkademo;
2 |
3 | import org.apache.kafka.clients.producer.Partitioner;
4 | import org.apache.kafka.common.Cluster;
5 | import org.apache.kafka.common.PartitionInfo;
6 | import org.apache.kafka.common.record.InvalidRecordException;
7 | import org.apache.kafka.common.utils.Utils;
8 |
9 | import java.util.List;
10 | import java.util.Map;
11 |
12 | /**
13 | * CustomKafkaPartitioner for 自定义消息分配器
14 | *
15 | * @author Isaac.Zhang | 若初
16 | * @since 2019/8/14
17 | */
18 | public class CustomKafkaPartitioner implements Partitioner {
19 |
20 | /**
21 | * 决定消息将被写入哪个分区
22 | *
23 | * @param cluster kafka集群信息
24 | */
25 | @Override
26 | public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
27 |
28 | //获取集群中topic对应的所有的partition
29 | List partitionInfoList = cluster.partitionsForTopic(topic);
30 | int partitionCount = 0;
31 | //获取partition 个数
32 | if (null != partitionInfoList && partitionInfoList.size() > 0) {
33 | partitionCount = partitionInfoList.size();
34 | }
35 |
36 | //自定义一个分区规则,必须传递消息的key,如果不传,则报错
37 | if (null == keyBytes || !(key instanceof String)) {
38 | throw new InvalidRecordException("Kafka message key is invalid.");
39 | }
40 | if (partitionCount == 1) {
41 | return 0;
42 | }
43 | switch (String.valueOf(key)) {
44 | case "demo-key":
45 | case "demo-asyn-key":
46 | case "demo-sync-key":
47 | case "demo-partitioner-key":
48 | return partitionCount - 1;
49 | }
50 |
51 | //使用kafka默认分区算法,murmur2获取字节数组hash值,然后对分区数取余
52 | return Math.abs(Utils.murmur2(keyBytes)) % (partitionCount - 1);
53 | }
54 |
55 | @Override
56 | public void close() {
57 |
58 | }
59 |
60 | @Override
61 | public void configure(Map configs) {
62 |
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/kafka-demo/src/main/java/com/sxzhongf/kafkademo/KafkaKeyCategory.java:
--------------------------------------------------------------------------------
1 | package com.sxzhongf.kafkademo;
2 |
3 | /**
4 | * KafkaKeyCategory for TODO
5 | *
6 | * @author Isaac.Zhang | 若初
7 | * @since 2019/8/14
8 | */
9 | public enum KafkaKeyCategory {
10 |
11 | asyn(0, "demo-asyn-key"),
12 | normal(1, "demo-key"),
13 | sync(2, "demo-sync-key");
14 |
15 | public int getCode() {
16 | return code;
17 | }
18 |
19 | public String getValue() {
20 | return value;
21 | }
22 |
23 | private int code;
24 | private String value;
25 |
26 | KafkaKeyCategory(int code, String value) {
27 | this.code = code;
28 | this.value = value;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/kafka-demo/src/main/java/com/sxzhongf/kafkademo/ProducerDemoCallback.java:
--------------------------------------------------------------------------------
1 | package com.sxzhongf.kafkademo;
2 |
3 | import org.apache.kafka.clients.producer.Callback;
4 | import org.apache.kafka.clients.producer.RecordMetadata;
5 |
6 | /**
7 | * ProducerDemoCallback for 实现异步生产消息结束后的回调处理
8 | *
9 | * @author Isaac.Zhang | 若初
10 | * @since 2019/8/14
11 | */
12 | public class ProducerDemoCallback implements Callback {
13 |
14 | @Override
15 | public void onCompletion(RecordMetadata recordMetadata, Exception exception) {
16 | if (null != exception) {
17 | System.out.println(exception.getStackTrace());
18 | return;
19 | }
20 | System.out.printf("Asyn Topic : %s, Partition: %s, Offset : %s \n"
21 | , recordMetadata.topic(), recordMetadata.partition(), recordMetadata.offset());
22 |
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/mscx-ad-common/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | mscx-ad
7 | com.sxzhongf
8 | 1.0-SNAPSHOT
9 | ../pom.xml
10 |
11 | 4.0.0
12 | jar
13 |
14 | com.sxzhongf
15 | mscx-ad-common
16 | 1.0-SNAPSHOT
17 | mscx-ad-common
18 | 公共逻辑 and 帮助类
19 |
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-starter-web
24 |
25 |
26 | com.alibaba
27 | fastjson
28 | 1.2.46
29 |
30 |
31 | commons-codec
32 | commons-codec
33 |
34 |
35 | org.apache.commons
36 | commons-lang3
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/mscx-ad-common/src/main/java/com/sxzhongf/ad/common/advice/CommonRequestAdvice.java:
--------------------------------------------------------------------------------
1 | package com.sxzhongf.ad.common.advice;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.core.MethodParameter;
5 | import org.springframework.http.HttpInputMessage;
6 | import org.springframework.http.converter.HttpMessageConverter;
7 | import org.springframework.web.bind.annotation.RestControllerAdvice;
8 | import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
9 |
10 | import java.io.IOException;
11 | import java.lang.reflect.Type;
12 |
13 | /**
14 | * CommonRequestAdvice for TODO
15 | *
16 | * @author Isaac.Zhang
17 | * @since 2019/6/13
18 | */
19 | @Slf4j
20 | @RestControllerAdvice
21 | public class CommonRequestAdvice implements RequestBodyAdvice {
22 | @Override
23 | public boolean supports(MethodParameter methodParameter, Type targetType, Class extends HttpMessageConverter>> converterType) {
24 | log.info("Sxzhongf -> CommonRequestAdvice#supports");
25 | return false;
26 | }
27 |
28 | @Override
29 | public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class extends HttpMessageConverter>> converterType) throws IOException {
30 | log.info("Sxzhongf -> CommonRequestAdvice#beforeBodyRead");
31 | return null;
32 | }
33 |
34 | @Override
35 | public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class extends HttpMessageConverter>> converterType) {
36 | log.info("Sxzhongf -> CommonRequestAdvice#afterBodyRead");
37 | return null;
38 | }
39 |
40 | @Override
41 | public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class extends HttpMessageConverter>> converterType) {
42 | log.info("Sxzhongf -> CommonRequestAdvice#handleEmptyBody");
43 | return null;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/mscx-ad-common/src/main/java/com/sxzhongf/ad/common/advice/CommonResponseDataAdvice.java:
--------------------------------------------------------------------------------
1 | package com.sxzhongf.ad.common.advice;
2 |
3 | import com.sxzhongf.ad.common.annotation.IgnoreResponseAdvice;
4 | import com.sxzhongf.ad.common.vo.CommonResponse;
5 | import org.springframework.core.MethodParameter;
6 | import org.springframework.http.MediaType;
7 | import org.springframework.http.converter.HttpMessageConverter;
8 | import org.springframework.http.server.ServerHttpRequest;
9 | import org.springframework.http.server.ServerHttpResponse;
10 | import org.springframework.web.bind.annotation.RestControllerAdvice;
11 | import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
12 |
13 | /**
14 | * CommonResponseDataAdvice for 统一拦截处理
15 | * 在响应体返回之前做一些处理;比如,修改返回值、加密等
16 | *
17 | * @author Isaac.Zhang
18 | * @see
19 | * @since 2019/6/13
20 | */
21 | @RestControllerAdvice
22 | public class CommonResponseDataAdvice implements ResponseBodyAdvice