<Spring Cloud>入門二 Eureka Client
阿新 • • 發佈:2019-01-12
1.搭建一個通用工程
1.1 pom 檔案
<?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>spring-cloud-learning</artifactId> <groupId>org.maple</groupId> <version>0.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>ms-common-api</artifactId> <dependencies><dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
1.2 資料庫表
Create Table CREATE TABLE `dept` ( `deptno` bigint(20) NOT NULL AUTO_INCREMENT, `dname` varchar(60) DEFAULT NULL, `db_source` varchar(60) DEFAULT NULL, PRIMARY KEY (`deptno`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
1.3 實體類
此處使用了 lombok,省去了getter/setter 等編寫
package org.maple.entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import java.io.Serializable; /** * @author mapleins * @Date 2019-01-08 21:35 * @Desc 部門實體類 **/ @AllArgsConstructor @NoArgsConstructor @Data @Accessors(chain = true) //可以鏈式程式設計 public class Dept implements Serializable { private Long deptNo; private String dName; private String db_source;//來自哪個資料庫 // public static void main(String[] args) { // Dept dept = new Dept(); // dept.setDeptNo(11l).setDName("技術部").setDb_source("dept"); //鏈式程式設計 // System.out.println(dept); // } }
2. 建立一個Department 的提供方,並且註冊服務到 eureka server 上
實現了查詢一個部門,查詢所有部門,新增一個部門的介面
專案結構:
2.1 pom 檔案
<?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>spring-cloud-learning</artifactId> <groupId>org.maple</groupId> <version>0.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>ms-provider-dept-8001</artifactId> <dependencies> <dependency> <groupId>org.maple</groupId> <artifactId>ms-common-api</artifactId> <version>0.0.1-SNAPSHOT</version> </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-web</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> </dependencies> </project>
2.2 編寫 application.yml 檔案
defaultZone 標識 註冊到哪個 Eureka Server 上
server:
port: 8001
eureka:
client:
service-url:
defaultZone: http://eureka-server01:8761/eureka/,http://eureka-server02:8762/eureka/
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml
type-aliases-package: org.maple.entity
mapper-locations: classpath:mybatis/mapper/**/*.xml
spring:
application:
name: ms-provider-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/cloudDB01
username: root
password: root
dbcp2:
min-idle: 5
initial-size: 5
max-total: 5
max-wait-millis: 200
2.3 編寫 mybatis 配置檔案,由於和spring整合後會將配置內容轉移到 Spring 配置檔案中,此處只是寫出來
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <setting name="cacheEnabled" value="true"/> </settings> </configuration>
2.4 編寫Dao層以及對映檔案mapper
package org.maple.dao; import org.apache.ibatis.annotations.Mapper; import org.maple.entity.Dept; import java.util.List; /** * @author mapleins * @Date 2019-01-08 22:31 * @Desc **/ @Mapper public interface DeptDao { boolean addDept(Dept dept); Dept findById(Long deptNo); List<Dept> findAll(); }
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespace 名稱空間 作用:用於繫結介面,即使用namespace將對映檔案和介面繫結,就不需要寫實現類了 --> <mapper namespace="org.maple.dao.DeptDao"> <select id="findById" resultType="org.maple.entity.Dept"> SELECT deptno deptNo,dname dName,db_source FROM dept WHERE deptno = #{deptNo} </select> <select id="findAll" resultType="org.maple.entity.Dept"> SELECT deptno deptNo,dname dName,db_source FROM dept </select> <insert id="addDept"> insert into dept(dname,db_source) VALUES (${dName},DATABASE()); </insert> </mapper>
2.5 編寫Service層
package org.maple.service; import org.maple.entity.Dept; import java.util.List; /** * @author mapleins * @Date 2019-01-08 22:41 * @Desc **/ public interface DeptService { boolean add(Dept dept); Dept find(Long deptNo); List<Dept> list(); }
package org.maple.service.impl; import org.maple.dao.DeptDao; import org.maple.entity.Dept; import org.maple.service.DeptService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * @author mapleins * @Date 2019-01-08 22:42 * @Desc **/ @Service public class DeptServiceImpl implements DeptService { @Autowired private DeptDao deptDao; @Override public boolean add(Dept dept) { return deptDao.addDept(dept); } @Override public Dept find(Long deptNo) { return deptDao.findById(deptNo); } @Override public List<Dept> list() { return deptDao.findAll(); } }
2.6 編寫controller 層
package org.maple.controller; import org.maple.entity.Dept; import org.maple.service.DeptService; import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*; import java.util.List; /** * @author mapleins * @Date 2019-01-08 22:45 * @Desc **/ @RestController public class DeptController { @Autowired private DeptService service; @PostMapping("/dept/add") public boolean add(@RequestBody Dept dept){ return service.add(dept); } @GetMapping("/dept/get/{id}") public Dept get(@PathVariable("id") Long id){ return service.find(id); } @GetMapping("/dept/list") public List<Dept> list(){ return service.list(); } }
2.7 編寫啟動類
此處新增 @EnableEurekaClient ,說明這是一個Eureka的客戶端,並將這個工程註冊到 Eureka註冊中心上
package org.maple; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient; /** * @author mapleins * @Date 2019-01-12 17:13 * @Desc **/ @SpringBootApplication @EnableEurekaClient public class App_Provider_Dept_8001 { public static void main(String[] args) { SpringApplication.run(App_Provider_Dept_8001.class,args); } }
2.8 啟動工程
我們可以看到 eureka 註冊中心出現了該服務的名字,說明註冊成功
服務的自己調自己也是成功的
3. 服務的發現
3.1 在 Controller 層 注入 @DiscoveryClient ,就可以顯示服務資訊
/** * 獲取服務資訊 */ @Autowired private DiscoveryClient client; @GetMapping("/dept/discovery") public Object discovery(){ List<String> services = client.getServices(); System.out.println("所有服務資訊:"+services); List<ServiceInstance> instances = client.getInstances("ms-provider-dept"); for (ServiceInstance instance : instances) { System.out.println("===========serviceId:"+instance.getServiceId()); System.out.println("===========host:"+instance.getHost()); System.out.println("===========port:"+instance.getPort()); System.out.println("===========uri:"+instance.getUri()); } return this.client; }
控制檯輸出
4. 配置 eureka info 中的資訊
4.1 父工程pom配置
新增maven外掛,將所有以 $[ ] 過濾
<build> <!--設定info下的資訊--> <resources> <resource> <directory>src\main\resources</directory> <filtering>true</filtering> </resource> </resources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <configuration> <delimiters> <delimiter>$[*]</delimiter> </delimiters> </configuration> </plugin> </plugins> </build>
4.2 在當前服務新增依賴
<!--管理監控--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
4.3 修改application.yml
info:
app.name: spring-cloud-learning
company.name: mapleins
build.artifactId: $[project.artifactId]
build.version: $[project.version]
4.4 點進eureka介面的下列位置後
出現如下:
5. 搭建一個消費者 來消費Department 的服務
工程結構:
5.1 pom檔案
<?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>spring-cloud-learning</artifactId> <groupId>org.maple</groupId> <version>0.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>ms-consumer-dept-80</artifactId> <dependencies> <dependency> <groupId>org.maple</groupId> <artifactId>ms-common-api</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
5.2 編寫yml檔案
server:
port: 80
5.3 配置config
@Configuration 代替了以前的 application.xml
注入一個 RestTemplate 來實現restful 呼叫
package org.maple.cfgbean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; /** * @author mapleins * @Date 2019-01-09 20:07 * @Desc spring application.xml -> @Configuration **/ @Configuration public class ConfigBean { @Bean public RestTemplate getRestTemplate(){ return new RestTemplate(); } }
5.4 編寫controller層
package org.maple.controller; import org.maple.entity.Dept; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import java.util.List; /** * @author mapleins * @Date 2019-01-09 20:10 * @Desc **/ @RestController public class DeptController_Consumer { private static final String REST_URL_PREFIX= "http://localhost:8001"; /** * 類似httpclient (url,requestMap,ResponseBean.class) * 請求地址,請求引數,http響應轉換的物件型別 */ @Autowired private RestTemplate restTemplate; @RequestMapping("/consumer/dept/add") public boolean add(Dept dept){ return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add",dept,Boolean.class); } @RequestMapping("/consumer/dept/get/{id}") public Dept get(@PathVariable("id") Long id){ return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id,Dept.class); } @RequestMapping("/consumer/dept/list") @SuppressWarnings("unchecked") public List<Dept> list(){ return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list",List.class); } @RequestMapping("/consumer/dept/discovery") public Object discovery(){ return restTemplate.getForObject(REST_URL_PREFIX+"/dept/discovery",Object.class); } }
5.5 編寫啟動類 並啟動
package org.maple; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author mapleins * @Date 2019-01-09 20:26 * @Desc **/ @SpringBootApplication public class App_Consumer_Dept_80 { public static void main(String[] args) { SpringApplication.run(App_Consumer_Dept_80.class, args); } }
頁面呼叫: