前一篇 基於docker部署的微服務架構(一):服務註冊中心 已經成功建立了一個服務註冊中心,如今咱們建立一個簡單的微服務,讓這個服務在服務註冊中心註冊。而後再建立一個調用者,調用此前建立的微服務。java
新建一個maven工程,修改pom.xml引入 spring cloud 依賴:git
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.2.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
在 resources 目錄中建立 application.yml 配置文件,在配置文件內容:spring
spring: application: name: @project.artifactId@ server: port: 8100 eureka: client: serviceUrl: defaultZone: http://localhost:8000/eureka/
這裏eureka的註冊地址爲上一篇中設置的defaultZone。
在 java 目錄中建立一個包 demo ,在包中建立啓動入口 AddServiceApplication.javadocker
@EnableDiscoveryClient @SpringBootApplication public class AddServiceApplication { public static void main(String[] args) { SpringApplication.run(AddServiceApplication.class, args); } }
在demo包下新建一個子包controller,在controller子包下建立一個controller對外提供接口。apache
@RestController public class AddController { @RequestMapping(value = "/add", method = RequestMethod.GET) public Map<String, Object> add(Integer a, Integer b) { System.out.println("端口爲8100的實例被調用"); Map<String, Object> returnMap = new HashMap<>(); returnMap.put("code", 200); returnMap.put("msg", "操做成功"); returnMap.put("result", a + b); return returnMap; } }
在服務註冊中心已經運行的狀況下,運行 AddServiceApplication.java 中的 main 方法,啓動微服務。
訪問服務註冊中心頁面 http://localhost:8000, 能夠看到已經成功註冊了 ADD-SERVICE-DEMO 服務。 瀏覽器
啓動第二個實例,修改端口爲 8101 ,修改 AddController.java 中的輸出信息爲tomcat
System.out.println("端口爲8101的實例被調用");
再次運行 AddServiceApplication.java 中的 main 方法。
訪問服務註冊中心頁面 http://localhost:8000, 能夠看到已經成功註冊了兩個 ADD-SERVICE-DEMO 服務,端口分別爲 8100 和 8101。
demo源碼 spring-cloud-1.0/add-service-demo安全
新建一個maven工程,修改pom.xml引入 spring cloud 依賴:架構
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.2.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
在 resources 目錄中建立 application.yml 配置文件,在配置文件內容:app
spring: application: name: @project.artifactId@ server: port: 8200 eureka: client: serviceUrl: defaultZone: http://localhost:8000/eureka/
在 java 目錄中建立一個包 demo ,在包中建立啓動入口 RibbonClientApplication.java
@EnableDiscoveryClient @SpringBootApplication public class RibbonClientApplication { public static void main(String[] args) { SpringApplication.run(RibbonClientApplication.class, args); } @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } }
這裏配置了一個能夠從服務註冊中心讀取服務列表,而且實現了負載均衡的 restTemplate。
在demo包下新建一個子包controller,在controller子包下建立一個controller對外提供接口。
@RestController public class RibbonController { @Autowired RestTemplate restTemplate; @RequestMapping(value = "/add", method = RequestMethod.GET) public String add(Integer a, Integer b) { return restTemplate.getForEntity("http://ADD-SERVICE-DEMO/add?a="+a+"&b=" + b, String.class).getBody(); } }
能夠看到這裏的請求url用了服務註冊中心對應的 Application。
運行 RibbonClientApplication.java 中的 main 方法,啓動項目。
在瀏覽器中訪問 http://localhost:8200/add?a=1&b=2 ,獲得返回結果:
{ msg: "操做成功", result: 3, code: 200 }
屢次訪問,查看 AddServiceApplication 的控制檯,能夠看到兩個 ADD-SERVICE-DEMO 被負載均衡的調用。
demo源碼 spring-cloud-1.0/ribbon-client-demo
新建一個maven工程,修改pom.xml引入 spring cloud 依賴:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.2.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
在 resources 目錄中建立 application.yml 配置文件,在配置文件內容:
spring: application: name: @project.artifactId@ server: port: 8300 eureka: client: serviceUrl: defaultZone: http://localhost:8000/eureka/
在 java 目錄中建立一個包 demo ,在包中建立啓動入口 FeignClientApplication.java
@EnableDiscoveryClient @SpringBootApplication @EnableFeignClients public class FeignClientApplication { public static void main(String[] args) { SpringApplication.run(FeignClientApplication.class, args); } }
在demo包下新建一個子包service,在service子包下建立一個接口 AddService.java 調用以前建立的微服務 ADD-SERVICE-DEMO。
@FeignClient("ADD-SERVICE-DEMO") public interface AddService { @RequestMapping(method = RequestMethod.GET, value = "/add") String add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b); }
這裏 @FeignClient
註解中的參數爲服務註冊中心對應的 Application。
在demo包下再新建一個子包controller,在controller子包下建立一個 FeignController.java 對外提供接口。
@RestController public class FeignController { @Autowired private AddService addService; @RequestMapping(value = "/add", method = RequestMethod.GET) public String add(Integer a, Integer b) { return addService.add(a, b); } }
FeignController 裏注入了剛纔建立的 AddService 接口。
運行 FeignClientApplication.java 中的 main 方法,啓動項目。
在瀏覽器中訪問 http://localhost:8300/add?a=1&b=2 ,獲得返回結果:
{ msg: "操做成功", result: 3, code: 200 }
屢次訪問,查看 AddServiceApplication 的控制檯,能夠看到兩個 ADD-SERVICE-DEMO 被負載均衡的調用。
demo源碼 spring-cloud-1.0/feign-client-demo
以 add-service-demo 爲例, 複製 application.yml,重命名爲 application-docker.yml,修改 defaultZone爲:
eureka: client: serviceUrl: defaultZone: http://service-registry:8000/eureka/
這裏修改了 defaultZone 的訪問url,如何修改取決於部署docker容器時的 --link 參數, --link 可讓兩個容器之間互相通訊。
修改 application.yml 中的 spring 節點爲:
spring: application: name: @project.artifactId@ profiles: active: @activatedProperties@
這裏增長了 profiles 的配置,在maven打包時選擇不一樣的profile,加載不一樣的配置文件。
在pom.xml文件中增長:
<properties> <java.version>1.8</java.version> <!-- 指定java版本 --> <!-- 鏡像前綴,推送鏡像到遠程庫時須要,這裏配置了一個阿里雲的私有庫 --> <docker.image.prefix> registry.cn-hangzhou.aliyuncs.com/ztecs </docker.image.prefix> <!-- docker鏡像的tag --> <docker.tag>demo</docker.tag> <!-- 激活的profile --> <activatedProperties></activatedProperties> </properties> <profiles> <!-- docker環境 --> <profile> <id>docker</id> <properties> <activatedProperties>docker</activatedProperties> <docker.tag>docker-demo-${project.version}</docker.tag> </properties> </profile> </profiles> <build> <defaultGoal>install</defaultGoal> <finalName>${project.artifactId}</finalName> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> <plugins> <!-- 配置spring boot maven插件,把項目打包成可運行的jar包 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <executable>true</executable> </configuration> </plugin> <!-- 打包時跳過單元測試 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <skipTests>true</skipTests> </configuration> </plugin> <!-- 配置docker maven插件,綁定install生命週期,在運行maven install時生成docker鏡像 --> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.4.13</version> <executions> <execution> <phase>install</phase> <goals> <goal>build</goal> <goal>tag</goal> </goals> </execution> </executions> <configuration> <!-- 修改這裏的docker節點ip,須要打開docker節點的遠程管理端口2375, 具體如何配置能夠參照以前的docker安裝和配置的文章 --> <dockerHost>http://docker節點ip:2375</dockerHost> <imageName>${docker.image.prefix}/${project.build.finalName}</imageName> <baseImage>java</baseImage> <!-- 這裏的entryPoint定義了容器啓動時的運行命令,容器啓動時運行 java -jar 包名 , -Djava.security.egd這個配置解決tomcat8啓動時, 由於須要收集環境噪聲來生成安全隨機數致使啓動過慢的問題--> <entryPoint> ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/${project.build.finalName}.jar"] </entryPoint> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> <image>${docker.image.prefix}/${project.build.finalName}</image> <newName>${docker.image.prefix}/${project.build.finalName}:${docker.tag}</newName> <forceTags>true</forceTags> <!-- 若是須要在生成鏡像時推送到遠程庫,pushImage設爲true --> <pushImage>false</pushImage> </configuration> </plugin> </plugins> </build>
選擇 docker
profile,運行 mvn install -P docker
,打包項目並生成docker鏡像,注意docker-maven-plugin中的 <entryPoint>
標籤裏的內容不能換行,不然在生成docker鏡像的時候會報錯。
運行成功後,登陸docker節點,運行 docker images
應該能夠看到剛纔打包生成的鏡像了。
在前一篇中,已經建立了一個 service-registry-demo 的docker鏡像,這裏先把這個鏡像運行起來。
docker run -d --name service-registry-demo --publish 8000:8000 \ --volume /etc/localtime:/etc/localtime \ registry.cn-hangzhou.aliyuncs.com/ztecs/service-registry-demo:docker-demo-1.0
對這條命令作個簡單說明, -d 指定當前容器運行在後臺, --name 指定容器名稱, --publish 指定端口映射到宿主機, --volume 這個掛載是爲了解決容器內的時區和宿主機不一致的問題,讓容器使用宿主機設置的時區,最後指定使用的docker鏡像,鏡像名稱和標籤須要根據本身的狀況作修改。
運行這條命令以後,service-registry-demo 的容器就啓動了。訪問 http://宿主機IP:8000
,打開註冊中心的頁面。
下邊啓動 add-service-demo 容器,
docker run -d --name add-service-demo --link service-registry-demo:service-registry --publish 8100:8100 \ --volume /etc/localtime:/etc/localtime \ registry.cn-hangzhou.aliyuncs.com/ztecs/add-service-demo:docker-demo-1.0
這條命令和上一條差很少,只是增長了一個 --link 參數,--link 指定容器間的鏈接,命令格式 --link 容器名:別名
,這裏鏈接了以前建立的名爲 service-registry-demo 的容器,這裏的別名和 application-docker.yml 文件中配置的 defaultZone 一致。其實就是經過別名找到了對應的容器IP,進到容器裏查看 hosts 文件就明白了,其實就是加了條hosts映射。
add-service-demo 容器啓動成功以後,刷新配置中心的頁面,發現已經註冊到配置中心了。