From a16c8e53008efff78a3b67ad5c5c3980672f0d5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=B9=E5=8D=87?= <xiangsheng.gh@alibaba-inc.com> Date: Sun, 5 May 2019 22:48:35 +0800 Subject: [PATCH] Add service module --- README.MD | 11 +++-- assets/service-architect.png | Bin 0 -> 16844 bytes pom.xml | 1 + service/pom.xml | 33 ++++++++++++++ service/service-api/pom.xml | 15 ++++++ .../com/aliware/tianchi/HashInterface.java | 18 ++++++++ service/service-consumer/pom.xml | 15 ++++++ service/service-provider/pom.xml | 23 ++++++++++ .../com/aliware/tianchi/HashServiceImpl.java | 43 ++++++++++++++++++ .../com/aliware/tianchi/HashInterface.java | 10 ++++ 10 files changed, 165 insertions(+), 4 deletions(-) create mode 100644 assets/service-architect.png create mode 100644 service/pom.xml create mode 100644 service/service-api/pom.xml create mode 100644 service/service-api/src/main/java/com/aliware/tianchi/HashInterface.java create mode 100644 service/service-consumer/pom.xml create mode 100644 service/service-provider/pom.xml create mode 100644 service/service-provider/src/main/java/com/aliware/tianchi/HashServiceImpl.java create mode 100644 service/src/main/java/com/aliware/tianchi/HashInterface.java diff --git a/README.MD b/README.MD index eba640e..5214bd2 100644 --- a/README.MD +++ b/README.MD @@ -14,13 +14,12 @@ ### Apache Dubbo Gateway - +TBD ### é¢˜ç›®ç”±æ¥ ä¼ ç»Ÿçš„è´Ÿè½½å‡è¡¡åœºæ™¯ä¸ºå•è°ƒåº¦å™¨æ¨¡å¼ï¼Œå³ä¸å¿ƒåŒ–è´Ÿè½½å‡è¡¡ï¼šè°ƒåº¦å™¨è´Ÿè´£å°†æ–°åˆ°çš„请求立å³è½¬å‘至多个åŽç«¯æœåŠ¡å™¨ä¸çš„一个。éšç€åˆ†å¸ƒå¼ç³»ç»Ÿçš„å‘展,这ç§å•è°ƒåº¦å™¨æ¨¡å¼åœ¨æ‰©å±•æ€§å’Œå¯é 性方é¢çš„问题也愈å‘严é‡ã€‚å› æ¤ï¼Œè®¾è®¡å’Œå®žçŽ°åŽ»ä¸å¿ƒåŒ–且性能优异的负载å‡è¡¡æ˜¯å¦æœ¯å’Œå·¥ä¸šç•Œçš„å…±åŒéœ€æ±‚。 - ## 赛题说明 按照题目æ供的扩展接å£ï¼Œå®žçŽ°ä¸€å¥—自适应负载å‡è¡¡æœºåˆ¶ã€‚è¦æ±‚能够具备以下能力: @@ -29,9 +28,13 @@ 2. Provider 端能自动进行æœåŠ¡å®¹é‡è¯„估,当请求数é‡è¶…过æœåŠ¡èƒ½åŠ›æ—¶ï¼Œå…许拒ç»éƒ¨åˆ†è¯·æ±‚,以ä¿è¯æœåŠ¡ä¸è¿‡è½½ã€‚ 3. 当请求速率高于所有的 Provider æœåŠ¡æ•ˆçŽ‡ä¹‹å’Œæ—¶ï¼Œå…许 Gateway( Consumer ) æ‹’ç»æœåŠ¡æ–°åˆ°è¯·æ±‚。 - ### 架构 -TBD + + +- Gateway 负责将请求转å‘至 Providerï¼› +- Provider 处ç†è¯·æ±‚返回å“应; +- Provider 按照 CPU æ ¸æ•°å’Œå†…å˜å¤§å°åˆ†ä¸º Smallã€Mediumã€Large ä¸‰ä¸ªè§„æ ¼ï¼› +- 选手需è¦è®¾è®¡å®žçŽ° Gateway 选择 Provider çš„ loadbalance 算法。 ### æœåŠ¡ diff --git a/assets/service-architect.png b/assets/service-architect.png new file mode 100644 index 0000000000000000000000000000000000000000..4df4e033f24d523160ee3c606f6852076e831830 GIT binary patch literal 16844 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%0DMc}P2u>bKXshu^m0 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 IdK2{j0Ao0E3jhEB literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml index 0542f3f..3055949 100644 --- a/pom.xml +++ b/pom.xml @@ -26,5 +26,6 @@ <modules> <module>internal-dubbo</module> <module>internal-gateway</module> + <module>service</module> </modules> </project> \ No newline at end of file diff --git a/service/pom.xml b/service/pom.xml new file mode 100644 index 0000000..851b006 --- /dev/null +++ b/service/pom.xml @@ -0,0 +1,33 @@ +<?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>adaptive-loadbalance</artifactId> + <groupId>com.aliware.tianchi</groupId> + <version>1.0.0</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>service</artifactId> + <packaging>pom</packaging> + <modules> + <module>service-api</module> + <module>service-consumer</module> + <module>service-provider</module> + </modules> + + <dependencies> + <dependency> + <groupId>com.aliware.tianchi</groupId> + <artifactId>internal-dubbo</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.aliware.tianchi</groupId> + <artifactId>internal-gateway</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + +</project> \ No newline at end of file diff --git a/service/service-api/pom.xml b/service/service-api/pom.xml new file mode 100644 index 0000000..0f3df87 --- /dev/null +++ b/service/service-api/pom.xml @@ -0,0 +1,15 @@ +<?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>service</artifactId> + <groupId>com.aliware.tianchi</groupId> + <version>1.0.0</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>service-api</artifactId> + + +</project> \ No newline at end of file diff --git a/service/service-api/src/main/java/com/aliware/tianchi/HashInterface.java b/service/service-api/src/main/java/com/aliware/tianchi/HashInterface.java new file mode 100644 index 0000000..087dfce --- /dev/null +++ b/service/service-api/src/main/java/com/aliware/tianchi/HashInterface.java @@ -0,0 +1,18 @@ +package com.aliware.tianchi; + +/** + * @author guohaoice@gmail.com + */ +public interface HashInterface { + + /** + * 计算给定å—符串的 hash 值 + * <li> + * <ol>接å£çš„å“应时间符åˆè´ŸæŒ‡æ•°åˆ†å¸ƒ </ol> + * <ol>接å£çš„并å‘度(å…许åŒæ—¶è°ƒç”¨çš„线程数)会éšæ—¶é—´å¢žåŠ 或å‡å°ï¼Œä»Žè€Œæ¨¡æ‹Ÿç”Ÿäº§çŽ¯å¢ƒå¯èƒ½çš„排队</ol> + * </li> + * @param input è¦è®¡ç®—çš„å—符串 + * @return å—符串的 hash 值 + */ + int hash(String input); +} diff --git a/service/service-consumer/pom.xml b/service/service-consumer/pom.xml new file mode 100644 index 0000000..ba938d8 --- /dev/null +++ b/service/service-consumer/pom.xml @@ -0,0 +1,15 @@ +<?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>service</artifactId> + <groupId>com.aliware.tianchi</groupId> + <version>1.0.0</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>service-consumer</artifactId> + + +</project> \ No newline at end of file diff --git a/service/service-provider/pom.xml b/service/service-provider/pom.xml new file mode 100644 index 0000000..53c8fab --- /dev/null +++ b/service/service-provider/pom.xml @@ -0,0 +1,23 @@ +<?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>service</artifactId> + <groupId>com.aliware.tianchi</groupId> + <version>1.0.0</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>service-provider</artifactId> + + <dependencies> + <dependency> + <groupId>com.aliware.tianchi</groupId> + <artifactId>service-api</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + +</project> \ No newline at end of file diff --git a/service/service-provider/src/main/java/com/aliware/tianchi/HashServiceImpl.java b/service/service-provider/src/main/java/com/aliware/tianchi/HashServiceImpl.java new file mode 100644 index 0000000..4df1288 --- /dev/null +++ b/service/service-provider/src/main/java/com/aliware/tianchi/HashServiceImpl.java @@ -0,0 +1,43 @@ +package com.aliware.tianchi; + +import java.util.concurrent.ThreadLocalRandom; + +/** + * Hash service impl + * + * @author guohaoice@gmail.com + */ +public class HashServiceImpl implements HashInterface { + private long averageRTT; + private int maxConcurrency; + private String salt; + + public HashServiceImpl(long averageRTT, int maxConcurrency, String salt) { + this.averageRTT = averageRTT; + this.maxConcurrency = maxConcurrency; + this.salt = salt; + } + + @Override + public int hash(String input) { + long baseRtt = nextRTT(); + try { + Thread.sleep(baseRtt); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + return (input + salt).hashCode(); + } + + private long nextRTT() { + ThreadLocalRandom rng = ThreadLocalRandom.current(); + double u = rng.nextDouble(); + int x = 0; + double cdf = 0; + while (u >= cdf) { + x++; + cdf = 1 - Math.exp(-1.0 * 1 / averageRTT * x); + } + return x; + } +} diff --git a/service/src/main/java/com/aliware/tianchi/HashInterface.java b/service/src/main/java/com/aliware/tianchi/HashInterface.java new file mode 100644 index 0000000..5665174 --- /dev/null +++ b/service/src/main/java/com/aliware/tianchi/HashInterface.java @@ -0,0 +1,10 @@ +package com.aliware.tianchi; + +/** + * @author guohaoice@gmail.com + */ +public interface HashInterface { + + int hash(String input); + +} -- GitLab