本文代碼請參考《https://github.com/478632418/springcloud-eureka-server-client/tree/master/mall》、《https://github.com/478632418/springboot-eureka》html
本章節主要包含SpringCloud終端服務器註冊中心、服務提供者、服務器消費幾個角色的項目建立示例。java
咱們這裏選取Euerka做爲服務註冊發現框架,實際上能提供服務註冊與發現的框架並不止它一個,可是業界內使用這個還比較普遍,可是有人說它從2.0以後Netflix就不在維護它了,可是依然有很多公司還堅持選了它,由於它到2.0就已經很穩定了。git
Eureka是Netflix開發的服務發現框架,自己是一個基於REST的服務,主要用於定位運行在AWS域中的中間層服務,以達到負載均衡和中間層服務故障轉移的目的。SpringCloud將它集成在其子項目spring-cloud-netflix中,以實現SpringCloud的服務發現功能。github
Eureka包含兩個組件:Eureka Server和Eureka Client。web
Eureka Server:提供服務註冊服務,服務啓動後,服務會在Eureka Server中進行註冊,包括主機與端口號、服務版本號、通訊協議等。這樣Eureka Server中的服務註冊表中將會存儲全部可用的服務節點的信息,服務節點的信息能夠在界面中直觀的看到。spring
Eureka Server端支持集羣模式部署,首尾相連造成一個閉環便可,集羣中的不一樣服務註冊中心經過異步模式互相複製各自的狀態,這也意味着在給定的時間點每一個實例中存儲的全部服務的狀態可能存在不一致的現象。docker
Eureka Client:主要處理服務的註冊和發現。客戶端服務經過註冊和參數配置的方式,嵌入在客戶端應用程序的代碼中。在應用程序啓動時,Eureka客戶端向服務註冊中心註冊自身提供的服務,並週期性的發送心跳來更新它的服務租約。同時,它也能從服務端查詢當前註冊的服務信息並把它們緩存到本地並週期性的刷新服務狀態。express
服務調用:apache
服務消費者在獲取服務清單後,經過服務名能夠獲取具體提供服務的實例名和該實例的元數據信息。由於有這些服務實例的詳細信息,因此客戶端能夠根據本身的需求決定具體調用哪一個實例,在Ribbon中會默認採用輪詢的方式進行調用,從而實現客戶端的負載均衡。緩存
服務提供者與服務消費者之間調用關係:
1)服務註冊中心啓動;
2)服務提供者在啓動時,向註冊中心註冊本身提供的服務;
3)服務消費者在啓動時,向註冊中心訂閱本身所須要的服務;
4)註冊中心返回服務提供者地址給消費者;
5)服務消費者從提供者地址中調用消費者。
實際上在開發中過程當中Eureka Server就是註冊中心;Eureka Client就是服務提供者和消費者。
SpringCloud是要基於SpringBoot的,所以在根項目導入了SpringBoot的parent引用。
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.1.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent>
根項目命名爲mall,它包含了三個主要子模塊(,config是配置中心的一個實現,放在下一篇文章中學習):
server(maven module):Eureka Server(服務註冊中心)
provider(maven module):Eureka Client(服務提供者)+Actuator(服務器監控)
consumer(maven module):Eureka Client(服務器消費者)+Ribbon(負載均衡)+Actuator(服務器監控)
在上邊新建的Maven Project下新建server項目(maven module). server project就是服務註冊中心,這裏講會講解採用分佈式配置以及如何運行在docker container中。
1)修改server project的pom.xml
maven項目的名稱爲server,版本號爲1.0.0
<parent> <groupId>com.dx.mall</groupId> <artifactId>mall</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>com.mall</groupId> <artifactId>server</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <name>server</name> <description>mall-server</description>
引入springboot-web引用,由於springcloud須要依賴於springboot,咱們這裏做爲web項目所以引用springboot-web。
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-cloud.version>Finchley.SR2</spring-cloud.version> <docker.image.prefix>mall</docker.image.prefix> <java.version>1.8</java.version> <skipTests>true</skipTests> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </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>
上邊是springboot-web和eureka-server和dependencyManagement是必須的,而後引入docker-build maven插件,以來Dockerfile來實現生成image到docker。
<!-- 使用maven插件的install執行時,會自動建立、更新images。 使用時須要在根目錄下包含Dockerfile文件,不然會拋出異常。 --> <build> <finalName>server</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> <version>1.4.0</version> <executions> <execution> <id>build-image</id> <phase>package</phase> <goals> <goal>build</goal> </goals> </execution> </executions> <configuration> <repository>${docker.image.prefix}/${project.build.finalName}</repository> <tag>${version}</tag> <buildArgs> <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> </buildArgs> </configuration> </plugin> </plugins> </build>
finalName中制定了打包的包名,上邊plugins下包含兩個maven plugin,第一個是spring-boot maven編譯器,第二個就docker插件,構造docker image使用,須要在服務器端安裝docker。
爲了防止找不到包,引入maven倉庫。
<!-- 解決maven倉庫找不到jar問題 --> <repositories> <repository> <id>spring-milestone-repo</id> <url>http://repo.spring.io/milestone/</url> </repository> </repositories>
2)application.yml文件配置
application.yml中配置內容以下:
spring:
application:
name: mall-server
eureka:
# 關閉自我保護模式
# eureka.server.enable-self-preservation: false
instance:
prefer-ip-address: true
lease-expiration-duration-in-seconds: 30
lease-renewal-interval-in-seconds: 30
client:
registerWithEureka: false
fetchRegistry: false
healthcheck:
enabled: true
service-url:
defaultZone: http://slave1:8761/eureka/,http://slave2:8762/eureka/,http://slave3:8763/eureka/
server:
enable-self-preservation: true
info:
app:
name: ${spring.application.name}
description: Eureka 註冊中心
version: 1.0.0
---
spring:
profiles:
slave1
server:
port: 8761
eureka:
instance:
hostname: slave1
---
spring:
profiles:
slave2
server:
port: 8762
eureka:
instance:
hostname: slave2
---
spring:
profiles:
slave3
server:
port: 8763
eureka:
instance:
hostname: slave3
這裏至關於使用三個yml文件:application-slave1.yml,application-slave2.yml,application-slave3.yml(用法參考:https://docs.spring.io/spring-boot/docs/2.1.10.BUILD-SNAPSHOT/reference/html/howto-properties-and-configuration.html#howto-change-configuration-depending-on-the-environment)。只是配置方式不一樣罷了,這麼作的目的是爲了更方便在docker上部署分佈式eureka-server。實際上就是使用docker-compose(docker重排功能)實現分佈式部署。
其中info:下是actuator依賴配置爲了在euerka-server ui中展現更有用詳細信息,經過/info等地質訪問到的信息。
其中eureka:client中展現的信息是是否註冊自身等配置,service-url:defaultZone是用來eureka-server一塊兒組成集羣使用的,這個是必須配置的。
3)編寫入口類(com.mall.server.ServerApplication):
package com.mall.server; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; /** * 註冊中心 * * @version 1.0.0 */ @EnableEurekaServer @SpringBootApplication public class ServerApplication { public static void main(String[] args) { SpringApplication.run(ServerApplication.class, args); } }
其中@SpringBootApplicaiton是springboot項目中,制定項目啓動入口註解;
其中@EnableEurekaServer是註解該project爲Eureka-Server。
4)在server的根下建立Dockerfile
Dockerfile是docker maven plugin生成image時須要依賴的文件,不然沒法正確生成image,Dockerfile中配置信息以下:
# 基於哪一個鏡像 FROM java:8 # 將本地文件夾掛載到當前容器 VOLUME /tmp # 拷貝文件到容器,server.jar這裏是maven打包後的名字 ADD ./target/server.jar app.jar RUN bash -c 'touch /app.jar' # 配置容器啓動後執行的命令 ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
5)使用maven工具生成docker image
在eclipse中選中該server項目-》Run As-》Maven install進行項目編譯:
[INFO] Scanning for projects... [WARNING] [WARNING] Some problems were encountered while building the effective model for com.mall:server:jar:1.0.0 [WARNING] The expression ${version} is deprecated. Please use ${project.version} instead. [WARNING] [WARNING] It is highly recommended to fix these problems because they threaten the stability of your build. [WARNING] [WARNING] For this reason, future Maven versions might no longer support building such malformed projects. [WARNING] [INFO] [INFO] --------------------------< com.mall:server >--------------------------- [INFO] Building server 1.0.0 [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ server --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ server --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ server --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ server --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.22.1:test (default-test) @ server --- [INFO] Tests are skipped. [INFO] [INFO] --- maven-jar-plugin:3.1.0:jar (default-jar) @ server --- [INFO] Building jar: /Users/dz/work/springcloud-test/mall/server/target/server.jar [INFO] [INFO] --- spring-boot-maven-plugin:2.1.1.RELEASE:repackage (repackage) @ server --- [INFO] Replacing main artifact with repackaged archive [INFO] [INFO] --- dockerfile-maven-plugin:1.4.0:build (build-image) @ server --- [INFO] Building Docker context /Users/dz/work/springcloud-test/mall/server [INFO] [INFO] Image will be built as mall/server:1.0.0 [INFO] [INFO] Step 1/5 : FROM java:8 [INFO] [INFO] Pulling from library/java [INFO] Image 5040bd298390: Pulling fs layer ... [INFO] Image bb9cdec9c7f3: Extracting [INFO] Image bb9cdec9c7f3: Pull complete [INFO] Digest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d [INFO] Status: Downloaded newer image for java:8 [INFO] ---> d23bdf5b1b1b [INFO] Step 2/5 : VOLUME /tmp [INFO] [INFO] ---> Running in 44f90f8f1fb1 [INFO] Removing intermediate container 44f90f8f1fb1 [INFO] ---> 13d7c25e8287 [INFO] Step 3/5 : ADD ./target/server.jar app.jar [INFO] [INFO] ---> 54ecfa5e791d [INFO] Step 4/5 : RUN bash -c 'touch /app.jar' [INFO] [INFO] ---> Running in bf2cbe1b90f7 [INFO] Removing intermediate container bf2cbe1b90f7 [INFO] ---> 00c1f22288b9 [INFO] Step 5/5 : ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] [INFO] [INFO] ---> Running in 0c28ddc6d2ce [INFO] Removing intermediate container 0c28ddc6d2ce [INFO] ---> b195029b462d [INFO] [Warning] One or more build-args [JAR_FILE] were not consumed [INFO] Successfully built b195029b462d [INFO] Successfully tagged mall/server:1.0.0 [INFO] [INFO] Detected build of image with id b195029b462d [INFO] Building jar: /Users/dz/work/springcloud-test/mall/server/target/server-docker-info.jar [INFO] Successfully built mall/server:1.0.0 [INFO] [INFO] --- maven-install-plugin:2.5.2:install (default-install) @ server --- [INFO] Installing /Users/dz/work/springcloud-test/mall/server/target/server.jar to /opt/mvn_local_repo/com/mall/server/1.0.0/server-1.0.0.jar [INFO] Installing /Users/dz/work/springcloud-test/mall/server/pom.xml to /opt/mvn_local_repo/com/mall/server/1.0.0/server-1.0.0.pom [INFO] Installing /Users/dz/work/springcloud-test/mall/server/target/server-docker-info.jar to /opt/mvn_local_repo/com/mall/server/1.0.0/server-1.0.0-docker-info.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 11:12 min [INFO] Finished at: 2019-09-23T11:27:43+08:00 [INFO] ------------------------------------------------------------------------
或者
經過mvn命令mvn package來生成images
dx:server $ mvn package -Ddockerfile.skip=false
或
mvn clean package -Ddockerfile.skip=false
此時查看Docker上的images列表以下:
dx:~ $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE mall/server 1.0.0 b195029b462d 2 hours ago 735MB java 8 d23bdf5b1b1b 2 years ago 643MB
6)在server項目根下建立docker-componse.yml從新編排文件
version: '3.5' services: slave1: container_name: s1 image: mall/server:1.0.0 networks: - mall-server-net ports: - 8761:8761 environment: - SPRING_PROFILES_ACTIVE=slave1 slave2: container_name: s2 image: mall/server:1.0.0 networks: - mall-server-net ports: - 8762:8762 environment: - SPRING_PROFILES_ACTIVE=slave2 slave3: container_name: s3 image: mall/server:1.0.0 networks: - mall-server-net ports: - 8763:8763 environment: - SPRING_PROFILES_ACTIVE=slave3 networks: mall-server-net: name: mall-server-net driver: bridge
從新編排的目的:使用images運行多個實例到container。
執行docker-compose從新編排。
dx:springcloud-test $ cd mall/ dx:mall $ ls config consumer pom.xml product server src dx:mall $ cd server/ dx:server $ ls Dockerfile docker-compose.yml pom.xml src target dx:server $ docker-compose -f docker-compose.yml up -d Creating network "mall-server-net" with driver "bridge" Creating s1 ... done Creating s2 ... done Creating s3 ... done dx:server $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e4b21fd1eb29 mall/server:1.0.0 "java -Djava.securit…" 6 seconds ago Up 5 seconds 0.0.0.0:8761->8761/tcp s1 9c798524acb1 mall/server:1.0.0 "java -Djava.securit…" 6 seconds ago Up 5 seconds 0.0.0.0:8763->8763/tcp s3 bd047426e71b mall/server:1.0.0 "java -Djava.securit…" 6 seconds ago Up 5 seconds 0.0.0.0:8762->8762/tcp s2 dx:server $
此時訪問:http://localhost:8761,http://localhost:8762,http://localhost:8763都可以訪問到以下界面:
到這裏就說明eureka server已經成功部署並運行。源代碼參考:https://github.com/478632418/springcloud-eureka-server-client/tree/master/mall/server
在maill(maven project)下新建product project(maven module) ,用來實現服務提供者功能。
1)修改server project的pom.xml
maven項目的名稱爲product,版本號爲1.0.0,並引入eureka-client maven依賴。
<parent> <groupId>com.dx.mall</groupId> <artifactId>mall</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>com.dx.mall.product</groupId> <artifactId>product</artifactId> <version>1.0.0</version> <name>product</name> <url>http://maven.apache.org</url>
引入springboot-web引用,由於springcloud須要依賴於springboot,咱們這裏做爲web項目所以引用springboot-web。
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-cloud.version>Finchley.SR2</spring-cloud.version> <docker.image.prefix>mall</docker.image.prefix> <java.version>1.8</java.version> <skipTests>true</skipTests> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</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>
上邊是springboot-web和eureka-client和dependencyManagement是必須的,而後引入docker-build maven插件,用來Dockerfile來實現生成image到docker。
<!-- 使用maven插件的install執行時,會自動建立、更新images。 使用時須要在根目錄下包含Dockerfile文件,不然會拋出異常。 --> <build> <finalName>product</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> <version>1.4.0</version> <executions> <execution> <id>build-image</id> <phase>package</phase> <goals> <goal>build</goal> </goals> </execution> </executions> <configuration> <repository>${docker.image.prefix}/${project.build.finalName}</repository> <tag>${version}</tag> <buildArgs> <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> </buildArgs> </configuration> </plugin> </plugins> </build>
finalName中制定了打包的包名,上邊plugins下包含兩個maven plugin,第一個是spring-boot maven編譯器,第二個就docker插件,構造docker image使用,須要在服務器端安裝docker。
爲了防止找不到包,引入maven倉庫。
<!-- 解決maven倉庫找不到jar問題 --> <repositories> <repository> <id>spring-milestone-repo</id> <url>http://repo.spring.io/milestone/</url> </repository> </repositories>
2)application.yml文件配置
application.yml中配置內容以下:
spring:
application:
name: spring-cloud-producer
eureka:
client:
service-url:
defaultZone: http://slave1:8761/eureka/,http://slave2:8762/eureka/,http://slave3:8763/eureka/
instance:
preferIpAddress: true
info:
app:
name: ${spring.application.name}
description: Spring-Cloud-Producer
version: 1.0.0
build.artifactId: $project.artifactId$
build.version: $project.version$
---
spring:
profiles:
slave1
server:
port: 7761
eureka:
instance:
hostname: slave1
---
spring:
profiles:
slave2
server:
port: 7762
eureka:
instance:
hostname: slave2
---
spring:
profiles:
slave3
server:
port: 7763
eureka:
instance:
hostname: slave3
這裏至關於使用三個yml文件:application-slave1.yml,application-slave2.yml,application-slave3.yml。只是配置方式不一樣罷了,這麼作的目的是爲了更方便在docker上部署分佈式eureka-client服務提供者。實際上就是使用docker-compose(docker重排功能)實現分佈式部署。
其中info:下是actuator依賴配置爲了在euerka-server ui中展現更有用詳細信息,經過/info等地質訪問到的信息。
其中eureka:client:service-url:defaultZone是用來eureka-client發現eureka-server使用的,這個是必須配置的。
package org.product; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; /** * Hello world! * */ @SpringBootApplication @EnableEurekaClient public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
其中@SpringBootApplicaiton是springboot項目中,制定項目啓動入口註解;
其中@EnableEurekaClient是註解該project爲Eureka-Client。
4)編寫服務提供(org.product.controller.DemoController)類
package org.product.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class DemoController { @Value("${server.port}") String serverPort; @GetMapping("/getPortInfo") public String getPortInfo() { return "The port is "+serverPort; } }
5)在product的根下建立Dockerfile
Dockerfile是docker maven plugin生成image時須要依賴的文件,不然沒法正確生成image,Dockerfile中配置信息以下:
# 基於哪一個鏡像 FROM java:8 # 將本地文件夾掛載到當前容器 VOLUME /tmp # 拷貝文件到容器,product.jar這裏是maven打包後的名字 ADD ./target/product.jar product.jar RUN bash -c 'touch /product.jar' # 配置容器啓動後執行的命令 ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/product.jar"]
6)使用maven工具生成docker image
在eclipse中選中該server項目-》Run As-》Maven install進行項目編譯:
[INFO] Scanning for projects... [WARNING] [WARNING] Some problems were encountered while building the effective model for com.dx.mall.product:product:jar:1.0.0 [WARNING] The expression ${version} is deprecated. Please use ${project.version} instead. [WARNING] [WARNING] It is highly recommended to fix these problems because they threaten the stability of your build. [WARNING] [WARNING] For this reason, future Maven versions might no longer support building such malformed projects. [WARNING] [INFO] [INFO] --------------------< com.dx.mall.product:product >--------------------- [INFO] Building product 1.0.0 [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ product --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ product --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 2 source files to /Users/dz/work/springcloud-test/mall/product/target/classes [INFO] [INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ product --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /Users/dz/work/springcloud-test/mall/product/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ product --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to /Users/dz/work/springcloud-test/mall/product/target/test-classes [INFO] [INFO] --- maven-surefire-plugin:2.22.1:test (default-test) @ product --- [INFO] Tests are skipped. [INFO] [INFO] --- maven-jar-plugin:3.1.0:jar (default-jar) @ product --- [INFO] Building jar: /Users/dz/work/springcloud-test/mall/product/target/product.jar [INFO] [INFO] --- spring-boot-maven-plugin:2.1.1.RELEASE:repackage (repackage) @ product --- [INFO] Replacing main artifact with repackaged archive [INFO] [INFO] --- dockerfile-maven-plugin:1.4.0:build (build-image) @ product --- [INFO] Building Docker context /Users/dz/work/springcloud-test/mall/product [INFO] [INFO] Image will be built as mall/product:1.0.0 [INFO] [INFO] Step 1/5 : FROM java:8 [INFO] [INFO] Pulling from library/java [INFO] Digest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d [INFO] Status: Image is up to date for java:8 [INFO] ---> d23bdf5b1b1b [INFO] Step 2/5 : VOLUME /tmp [INFO] [INFO] ---> Using cache [INFO] ---> 13d7c25e8287 [INFO] Step 3/5 : ADD ./target/product.jar product.jar [INFO] [INFO] ---> 7f918fde0731 [INFO] Step 4/5 : RUN bash -c 'touch /product.jar' [INFO] [INFO] ---> Running in 368ce696cbd6 [INFO] Removing intermediate container 368ce696cbd6 [INFO] ---> 1fa85ed6c438 [INFO] Step 5/5 : ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/product.jar"] [INFO] [INFO] ---> Running in 5049235d2782 [INFO] Removing intermediate container 5049235d2782 [INFO] ---> 614560332af7 [INFO] [Warning] One or more build-args [JAR_FILE] were not consumed [INFO] Successfully built 614560332af7 [INFO] Successfully tagged mall/product:1.0.0 [INFO] [INFO] Detected build of image with id 614560332af7 [INFO] Building jar: /Users/dz/work/springcloud-test/mall/product/target/product-docker-info.jar [INFO] Successfully built mall/product:1.0.0 [INFO] [INFO] --- maven-install-plugin:2.5.2:install (default-install) @ product --- [INFO] Installing /Users/dz/work/springcloud-test/mall/product/target/product.jar to /opt/mvn_local_repo/com/dx/mall/product/product/1.0.0/product-1.0.0.jar [INFO] Installing /Users/dz/work/springcloud-test/mall/product/pom.xml to /opt/mvn_local_repo/com/dx/mall/product/product/1.0.0/product-1.0.0.pom [INFO] Installing /Users/dz/work/springcloud-test/mall/product/target/product-docker-info.jar to /opt/mvn_local_repo/com/dx/mall/product/product/1.0.0/product-1.0.0-docker-info.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 23.690 s [INFO] Finished at: 2019-09-23T23:38:03+08:00 [INFO] ------------------------------------------------------------------------
或者進入provider項目根目錄下,經過mvn命令mvn package來生成images
dx:provider $ mvn package -Ddockerfile.skip=false
或
mvn clean package -Ddockerfile.skip=false
此時查看Docker上的images列表以下:
dx:server $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE mall/product 1.0.0 614560332af7 About a minute ago 724MB mall/server 1.0.0 b195029b462d 12 hours ago 735MB java 8 d23bdf5b1b1b 2 years ago 643MB dx:server $
出現上邊信息說明已經成功生成了mall/product鏡像。
6)在product項目根下建立docker-componse.yml從新編排文件
version: '3.5' services: slave1: container_name: p1 image: mall/product:1.0.0 networks: - mall-server-net ports: - 7761:7761 environment: - SPRING_PROFILES_ACTIVE=slave1 slave2: container_name: p2 image: mall/product:1.0.0 networks: - mall-server-net ports: - 7762:7762 environment: - SPRING_PROFILES_ACTIVE=slave2 slave3: container_name: p3 image: mall/product:1.0.0 networks: - mall-server-net ports: - 7763:7763 environment: - SPRING_PROFILES_ACTIVE=slave3 networks: mall-server-net: name: mall-server-net driver: bridge
注意:
1)生成該編排文件時,必需要networks和以前server的networks共用一個,不然會致使出現後邊eureka-server和服務提供者(product)運行的容器的網段不在一塊兒,進而致使網絡沒法被訪問。
2)從新編排的目的:使用images運行多個實例到container。
執行docker-compose從新編排。
dx:server $ pwd /Users/dz/work/springcloud-test/mall/server dx:server $ cd .. dx:mall $ cd product/ dx:product $ ls Dockerfile docker-compose.yml pom.xml src target dx:product $ docker-compose -f docker-compose.yml up -d Creating p3 ... done Creating p2 ... done Creating p1 ... done dx:product $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ee3c8c4968eb mall/product:1.0.0 "java -Djava.securit…" 7 seconds ago Up 6 seconds 0.0.0.0:7762->7762/tcp p2 893af08a6d8a mall/product:1.0.0 "java -Djava.securit…" 7 seconds ago Up 6 seconds 0.0.0.0:7763->7763/tcp p3 02bea113a771 mall/product:1.0.0 "java -Djava.securit…" 7 seconds ago Up 6 seconds 0.0.0.0:7761->7761/tcp p1 e4b21fd1eb29 mall/server:1.0.0 "java -Djava.securit…" 10 hours ago Up 10 hours 0.0.0.0:8761->8761/tcp s1 9c798524acb1 mall/server:1.0.0 "java -Djava.securit…" 10 hours ago Up 10 hours 0.0.0.0:8763->8763/tcp s3 bd047426e71b mall/server:1.0.0 "java -Djava.securit…" 10 hours ago Up 10 hours 0.0.0.0:8762->8762/tcp s2 dx:product $
此時訪問:http://localhost:8761,http://localhost:8762,http://localhost:8763都可以訪問到以下界面:
到這裏就說明eureka provider已經成功部署並運行。
在mall下新建consumer(maven module)項目,pom.xml版本名稱修改:
1)修改server project的pom.xml
maven項目的名稱爲consumer,版本號爲1.0.0,並引入eureka-client maven依賴。
<parent> <groupId>com.dx.mall</groupId> <artifactId>mall</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>com.dx.mall.consumer</groupId> <artifactId>consumer</artifactId> <version>1.0.0</version> <name>consumer</name> <url>http://maven.apache.org</url>
引入springboot-web引用,由於springcloud須要依賴於springboot,咱們這裏做爲web項目所以引用springboot-web。
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-cloud.version>Finchley.SR2</spring-cloud.version> <docker.image.prefix>mall</docker.image.prefix> <java.version>1.8</java.version> <skipTests>true</skipTests> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <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-ribbon</artifactId>
</dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</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>
上邊是springboot-web和eureka-client和dependencyManagement是必須的,而後引入docker-build maven插件,用來Dockerfile來實現生成image到docker。
<!-- 使用maven插件的install執行時,會自動建立、更新images。 使用時須要在根目錄下包含Dockerfile文件,不然會拋出異常。 --> <build> <finalName>consumer</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> <version>1.4.0</version> <executions> <execution> <id>build-image</id> <phase>package</phase> <goals> <goal>build</goal> </goals> </execution> </executions> <configuration> <repository>${docker.image.prefix}/${project.build.finalName}</repository> <tag>${version}</tag> <buildArgs> <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> </buildArgs> </configuration> </plugin> </plugins> </build>
finalName中制定了打包的包名,上邊plugins下包含兩個maven plugin,第一個是spring-boot maven編譯器,第二個就docker插件,構造docker image使用,須要在服務器端安裝docker。
爲了防止找不到包,引入maven倉庫。
<!-- 解決maven倉庫找不到jar問題 --> <repositories> <repository> <id>spring-milestone-repo</id> <url>http://repo.spring.io/milestone/</url> </repository> </repositories>
2)application.yml文件配置
application.yml中配置內容以下:
spring: application: name: spring-cloud-consumer eureka: client: service-url: defaultZone: http://slave1:8761/eureka/,http://slave2:8762/eureka/,http://slave3:8763/eureka/ instance: preferIpAddress: true info: app: name: ${spring.application.name} description: Spring-Cloud-Consumer version: 1.0.0 build.artifactId: $project.artifactId$ build.version: $project.version$ #取消Ribbon使用Eureka #ribbon: # eureka: # enabled: true #配置Ribbon能訪問 的微服務節點,多個節點用逗號隔開 #spring-cloud-consumer: # ribbon: # listOfServers: localhost:8001,localhost:8002 --- spring: profiles: slave1 server: port: 6761 management: port: 54001 health: mail: enabled: false eureka: instance: hostname: slave1
這裏配置了一個application.yml的標籤
package org.consumer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
/**
* Hello world!
*
*/
@SpringBootApplication
@EnableEurekaClient
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
// 負載均衡策略
@Bean
public IRule myRule() {
return new RandomRule();
}
}
其中@SpringBootApplicaiton是springboot項目中,制定項目啓動入口註解;
其中@EnableEurekaClient是註解該project爲Eureka-Client。
4)編寫服務提供(org.consumer.controller.DemoController)類
package org.consumer.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class RibbonController {
@Autowired
RestTemplate restTemplate;
@GetMapping("/getProviderInfo")
public String getProviderInfo() {
String result = this.restTemplate.getForObject("http://spring-cloud-producer/getPortInfo", String.class);
return result;
}
}
注意:上邊代碼中訪問provider的url(http://spring-cloud-producer/)實際上是 provider項目中application.yml中的配置項spring.application.name配置的值。
5)在product的根下建立Dockerfile
Dockerfile是docker maven plugin生成image時須要依賴的文件,不然沒法正確生成image,Dockerfile中配置信息以下:
# 基於哪一個鏡像
FROM java:8 # 將本地文件夾掛載到當前容器 VOLUME /tmp # 拷貝文件到容器,consumer.jar這裏是maven打包後的名字 ADD ./target/consumer.jar consumer.jar RUN bash -c 'touch /consumer.jar' # 配置容器啓動後執行的命令 ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/consumer.jar"]
6)使用maven工具生成docker image
在eclipse中選中該consumer項目-》Run As-》Maven install進行項目編譯就會經過mvn docker插件將生成images到本地docker上。
或者經過mvn命令也行:
進入consumer項目根目錄下,經過mvn命令mvn package來生成images
dx:provider $ mvn package -Ddockerfile.skip=false
或
mvn clean package -Ddockerfile.skip=false
此時查看Docker上的images列表以下:
dx:server $ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mall/product 1.0.0 614560332af7 About 1 hours ago 724MB mall/server 1.0.0 b195029b462d 12 hours ago 735MB
mall/consumer 1.0.0 iudksjd95029 About a minute ago 733MB
java 8 d23bdf5b1b1b 2 years ago 643MB dx:server $
出現上邊信息說明已經成功生成了mall/consumer鏡像。
7)在consumer項目根下建立docker-componse.yml從新編排文件,文件內容以下:
version: '3.5' services: slave1: container_name: c1 image: mall/consumer:1.0.0 networks: - mall-server-net ports: - 6761:6761 environment: - SPRING_PROFILES_ACTIVE=slave1 networks: mall-server-net: name: mall-server-net driver: bridge
經過docker-compose構建container時,這裏指定只啓動一個cotainer實例。
執行docker-compose從新編排。
dx:server $ pwd
/Users/dz/work/springcloud-test/mall/server dx:server $ cd .. dx:mall $ cd consumer/ dx:consumer $ ls Dockerfile docker-compose.yml pom.xml src target dx:consumer $ docker-compose -f docker-compose.yml up -d Creating c1 ... done dx:consumer $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ee3c8c4968eb mall/product:1.0.0 "java -Djava.securit…" 1 hours ago Up 1 hours 0.0.0.0:7762->7762/tcp p2 893af08a6d8a mall/product:1.0.0 "java -Djava.securit…" 1 hours ago Up 1 hours 0.0.0.0:7763->7763/tcp p3 02bea113a771 mall/product:1.0.0 "java -Djava.securit…" 1 hours ago Up 1 hours 0.0.0.0:7761->7761/tcp p1 e4b21fd1eb29 mall/server:1.0.0 "java -Djava.securit…" 10 hours ago Up 10 hours 0.0.0.0:8761->8761/tcp s1 9c798524acb1 mall/server:1.0.0 "java -Djava.securit…" 10 hours ago Up 10 hours 0.0.0.0:8763->8763/tcp s3 bd047426e71b mall/server:1.0.0 "java -Djava.securit…" 10 hours ago Up 10 hours 0.0.0.0:8762->8762/tcp s2
ioweu2992333 mall/consumer:1.0.0 "java -Djava.securit…" 7 seconds ago Up 6 seconds 0.0.0.0:6761->6761/tcp c1
dx:consumer $
此時說明consumer容器已經啓動,訪問路徑:http://slave1:6761/getProviderInfo
此時可能返回:The port is 7762
刷新後返回信息端口號會變化。
其餘資源相同資源可參考: