環境:win10--idea2019--jdk8
1.搭建Eureka服務模塊
1.1 新建eureka服務模塊(Sping Initializr)
取名為eureka-server
,並添加如下Dependencies:
1.2 配置application.properties
#配置端口 server.port=8761 #spring 的應用名=一般是模塊名 spring.application.name=eureka-server #當前模塊是否注冊為eureka的客戶端 # --->因為當前應用應該是服務端 # --->所以選false eureka.client.register-with-eureka=false #既然不是客戶端,那么是否 # 在Server Center 注冊? # --->不要,因為當前應用本來就是server eureka.client.fetch-registry=false #------------------------------------------ #eureka.客戶端.服務url.默認區域,${server.port} 動態獲取port-->即第1行的8761 eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka
1.3 在啟動類前加上注解@EnableEurekaServer
//啟用Eureka服務器 @EnableEurekaServer @SpringBootApplication public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }
1.4 開啟啟動器,並訪問,測試是否正確配置eureka的服務端
本機訪問http://localhost:8761/
有畫面則說明啟動成功
2.編寫公共的實體類模塊
2.1 新建普通maven-quickstart工程
2.2 在pom文件中添加lombok坐標(用於簡化實體類)
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.10</version> </dependency> </dependencies>
2.3 編寫實體類
@Data @AllArgsConstructor @NoArgsConstructor public class Dept implements Serializable { private Integer deptno; private String dname; private String loc; }
@Data @AllArgsConstructor @NoArgsConstructor public class Emp implements Serializable { private Integer empno; private String ename; private String job; private Integer mgr; private java.sql.Date hiredate; private Double sal; private Double comm; private Integer deptno; }
2.4 然后用maven打包工具先clean
然后再install
打包到本地倉庫
2.4.1 檢查本地倉庫是否有對應的jar
如上圖,有就行了...
3. 編寫provider-one模塊
3.1 新建Spring Initializr
工程
3.2 在pom中加入公共實體類的依賴,並修改數據庫驅動版本號為5.1.38
<dependency> <groupId>cn.kgc</groupId> <artifactId>employee-common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <!--修改版本號--> <version>5.1.38</version> </dependency>
3.3 編寫 實體類的mapper
DeptMapper.java
@Mapper public interface DeptMapper { @Select("select * from dept") List<Map<String,Object>>selAllDeptData(); }
3.4 編寫service
DeptService.java
public interface DeptService { List<Map<String,Object>> optionData(); }
3.5 編寫serviceImpl
DeptServiceImpl.java
@Service public class DeptServiceImpl implements DeptService { @Autowired private DeptMapper deptMapper; @Override public List<Map<String, Object>> optionData() { return deptMapper.selAllDeptData(); } }
3.6 編寫中心控制類
CenterController.java
@RestController public class CenterController { @Autowired private DeptService deptService; @GetMapping("/optionData.do") public List<Map<String, Object>> optionData() { return deptService.optionData(); } }
3.7 編寫配置文件
application.properties
#服務端口號 server.port=8762 #應用名 spring.application.name=provider #eureka客戶端服務url默認區域 eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ #數據源驅動類名 spring.datasource.driver-class-name=com.mysql.jdbc.Driver #數據源url,www.52cc.monster為我的服務器,但是可能在國外,time out 惡心死我了 還是用回localhost或者國內阿里的 spring.datasource.url=jdbc:mysql://www.52cc.monster:3306/kh75 #數據源用戶名 spring.datasource.username=root #數據源密碼 spring.datasource.password=**** #后期會寫mapper.xml,這里先注釋 #mybatis.mapper-locations=classpath:mapper/*.xml #給實體類起別名,同樣這里先注釋 #mybatis.type-aliases-package=cn.kgc.vo
3.8 在啟動類上加注解
ProviderOneApplication.java
//啟用eureka客戶端 @EnableEurekaClient //Mapper掃描,對應的mapper包 @MapperScan("cn.kgc.mapper") @SpringBootApplication public class ProviderOneApplication { public static void main(String[] args) { SpringApplication.run(ProviderOneApplication.class, args); } }
4.編寫consumer模塊
4.1 新建Spring Initializr
工程
4.2 在pom中加入公共實體類的依賴
<dependency> <groupId>cn.kgc</groupId> <artifactId>employee-common</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
4.3 編寫Feign包下的類
CenterFeign.java
@FeignClient(value="provider",fallback = ICenterFeign.class)
public interface CenterFeign {
@GetMapping("/showCate.do")
public List<Map<String,Object>> showCate();
@PostMapping("/showDetail.do")
public List<Map<String, Object>> showDetail( @RequestBody Newsdetail newsdetail);
@PostMapping("/addDetail.do")
public int addDetail(@RequestBody Newsdetail newsdetail);
@PostMapping("/editDetail.do")
public int editDetail( @RequestBody Newsdetail newsdetail);
@GetMapping("/delDetail.do")
public int delDetail(@RequestParam("id") Integer id);
}
CenterFeign.java
@Component
public class ICenterFeign implements CenterFeign{
@Override
public List<Map<String, Object>> showCate() {
Map<String,Object>map=new HashMap<String,Object>();
List<Map<String,Object>> list=new ArrayList<>();
map.put("msg"," showCate error");
list.add(map);
return list;
}
@Override
public List<Map<String, Object>> showDetail(Newsdetail newsdetail) {
Map<String,Object>map=new HashMap<String,Object>();
List<Map<String,Object>> list=new ArrayList<>();
map.put("msg"," showDetail error");
list.add(map);
return list;
}
@Override
public int addDetail(Newsdetail newsdetail) {
return 0;
}
@Override
public int editDetail(Newsdetail newsdetail) {
return 0;
}
@Override
public int delDetail(Integer id) {
return 0;
}
}
4.4 編寫中心控制類CenterController
CenterController.java
@RestController public class CenterController { @Autowired private CenterFeign centerFeign; @GetMapping("/optionData-consumer.do") public List<Map<String, Object>> optionData() { return centerFeign.optionData(); } }
4.5 編寫配置文件
application.properties
#端口號 server.port=8764 #應用名 spring.application.name=consumer #eureka客戶端服務url默認區域 eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ #下線名稱.ribbon.NF加載平衡規則類名,這里先注釋 #provider.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
#將feign集成的斷路器設置有效狀態
feign.hystrix.enabled=true
4.6在啟動類上添加注解
ConsumerApplication.java
//開啟Feign客戶端 @EnableFeignClients //開啟eureka客戶端 @EnableEurekaClient @SpringBootApplication public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
5.編寫zuul網關模塊

5.2配置文件 application.properties
5.3 pom.xml文件配置
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</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-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
6.用postman測試接口
已查出數據....
6. 重復以上3.3-4中步驟,建立新的mapper
6.1 更新provider-one模塊
EmpMapper.java
public interface EmpMapper { @Select( "<script>" + " select d.dname,d.loc,e.* from emp e,dept d WHERE e.deptno=d.deptno" + " <if test='deptno!=-1 and deptno!=null'>" + " and e.deptno=#{deptno}" + " </if>" + " <if test='empno!=null'>" + " and e.empno=#{empno}" + " </if>" + "</script>" ) List<Map<String,Object>> selEmpData(Emp emp); @Insert("insert into emp(empno,ename,sal,job,deptno) values(#{empno},#{ename},#{sal},#{job},#{deptno})") Integer insert(Emp emp); @Update("update emp set ename=#{ename},sal=#{sal},job=#{job},deptno=#{deptno} where empno=#{empno}") Integer updEmp(Emp emp); @Delete("delete from emp where empno=#{empno}") Integer delEmpByPrimaryKey(Integer empno); }
EmpService.java
public interface EmpService { List<Map<String,Object>> showEmpData(Emp emp); Integer add(Emp emp); Integer edit(Emp emp); Integer del(Integer empno); }
EmpServiceImpl.java
@Service @Transactional public class EmpServiceImpl implements EmpService { @Autowired private EmpMapper empMapper; @Override public List<Map<String, Object>> showEmpData(Emp emp) { return empMapper.selEmpData(emp); } @Override public Integer add(Emp emp) { return empMapper.insert(emp); } @Override public Integer edit(Emp emp) { return empMapper.updEmp(emp); } @Override public Integer del(Integer empno) { return empMapper.delEmpByPrimaryKey(empno); } }
更新中心控制類
CenterController.java
@RestController public class CenterController { @Autowired private DeptService deptService; @Autowired private EmpService empService; @GetMapping("/optionData.do") public List<Map<String, Object>> optionData() { return deptService.optionData(); } @PostMapping("/showEmpData.do") //Feign:不支持對象傳參,所以要用@RequestBody public List<Map<String, Object>> showEmpData(@RequestBody Emp emp) { return empService.showEmpData(emp); } @PostMapping("/add.do") public Integer add(@RequestBody Emp emp) { return empService.add(emp); } @PostMapping("/edit.do") public Integer edit(@RequestBody Emp emp) { return empService.edit(emp); } @GetMapping("/del.do") public Integer del(@RequestParam("empno") Integer empno) { return empService.del(empno); } }
6.2 更新consumer模塊
更新feign類
@FeignClient(name = "provider") public interface CenterFeign { @GetMapping("/optionData.do") public List<Map<String, Object>> optionData(); @PostMapping("/showEmpData.do") //Feign:不支持對象傳參,所以要用@RequestBody public List<Map<String, Object>> showEmpData(@RequestBody Emp emp); @PostMapping("/add.do") public Integer add(@RequestBody Emp emp); @PostMapping("/edit.do") public Integer edit(@RequestBody Emp emp); @GetMapping("/del.do") public Integer del(@RequestParam("empno") Integer empno); }
更新consumer的controller
@RestController public class CenterController{ @Autowired private CenterFeign centerFeign; @GetMapping("/optionData-consumer.do") public List<Map<String, Object>> optionData() { return centerFeign.optionData(); } @PostMapping("/showEmpData-consumer.do") public List<Map<String, Object>> showEmpData(@RequestBody Emp emp) { return centerFeign.showEmpData(emp); } @PostMapping("/add-consumer.do") public Integer add(@RequestBody Emp emp) { return centerFeign.add(emp); } @PostMapping("/edit-consumer.do") public Integer edit(@RequestBody Emp emp) { return centerFeign.edit(emp); } @GetMapping("/del-consumer.do") public Integer del(@RequestParam("empno") Integer empno) { return centerFeign.del(empno); } }
再用postman測試,都沒有問題
注意,這里測試的都是http://localhost:8764/XXX-consumer.do
的url
XXX為consumer的controller中的Mapping映射
7. 新建provider-two模塊
步驟和3一樣,就名改成two
7.1 在pom中加入公共實體類的依賴,並修改數據庫驅動版本號為5.1.38
<dependency> <groupId>cn.kgc</groupId> <artifactId>employee-common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <!--修改版本號--> <version>5.1.38</version> </dependency>
7.2 把one的cn.kgc下的包都扒拉過來
7.3 再更新啟動類,加注解,也直接扒拉
//啟用eureka客戶端 @EnableEurekaClient //Mapper掃描,對應的mapper包 @MapperScan("cn.kgc.mapper") @SpringBootApplication public class ProviderTwoApplication { public static void main(String[] args) { SpringApplication.run(ProviderTwoApplication.class, args); } }
7.4 再更新配置文件application.properties
,也直接扒拉,把端口號改一改
#服務端口號 server.port=8763 #應用名 spring.application.name=provider #eureka客戶端服務url默認區域 eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ #數據源驅動類名 spring.datasource.driver-class-name=com.mysql.jdbc.Driver #數據源url spring.datasource.url=jdbc:mysql:///kh75 #數據源用戶名 spring.datasource.username=root #數據源密碼 spring.datasource.password=admin #后期會寫mapper.xml,這里先注釋 #mybatis.mapper-locations=classpath:mapper/*.xml #給實體類起別名,同樣這里先注釋 #mybatis.type-aliases-package=cn.kgc.vo
8. 更新consumer中的配置文件,把原來注釋的下線放出來
application.properties
#端口號 server.port=8764 #應用名 spring.application.name=consumer #eureka客戶端服務url默認區域 eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ #下線名稱.ribbon.NF加載平衡規則類名,默認是輪詢,現在改為隨機,RandomRule:隨機選擇一個服務節點 provider.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
9. 為了看清楚是不是隨機,在這加控制台打印
9.1 在provider-one 的控制類的 /showEmpData.do
中加打印
@PostMapping("/showEmpData.do") //Feign:不支持對象傳參,所以要用@RequestBody public List<Map<String, Object>> showEmpData(@RequestBody Emp emp) { System.out.println("provider-one>>>>"+emp); return empService.showEmpData(emp); }
9.2 在provider-two 的控制類的 /showEmpData.do
中加打印
@PostMapping("/showEmpData.do") //Feign:不支持對象傳參,所以要用@RequestBody public List<Map<String, Object>> showEmpData(@RequestBody Emp emp) { System.out.println("provide-two>>>>"+emp); return empService.showEmpData(emp); }
9.3 這里只用postman測 /showEmpData-consumer.do
測10次看后台打印是不是隨機的
9.3.1 結果
one:有6個
two:有4個
所以負載均衡策略是隨機的
那現在把上面的注釋
#下線名稱.ribbon.NF加載平衡規則類名,這里先注釋provider.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
還是測10次,結果:
one:5次
two:5次
為了防止巧合,再測10次一共20次,結果:
one:10次
two:10次
所以,以下這句話起作用了
#下線名稱.ribbon.NF加載平衡規則類名,這里先注釋provider.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
10.整體結構圖
10.1employee-common
10.2eureka-server
10.3employee-common
10.4provider-one
10.5provider-two
10.6consumer
11.拓展,Ribbon提供的7種負載均衡策略:
Ribbon提供了多鍾負載均衡策略:
1 WeightedResponseTimeRule:根據響應時間分配一個weight(權重,大小的概念),響應時間和weight成反比
2.RoundRobinRule:輪詢選擇服務節點(默認的負載均衡策略)
3.RandomRule:隨機選擇一個服務節點
4.ZoneAvoidanceRule:綜合考慮服務節點所在區域的性能和服務節點的可用性來選擇服務節點
5.RetryRule:重試機制.在一個配置時間段內,當選擇服節點不成功時會一直嘗試重新選擇
6.BestAvailableRule:選擇一個並發請求最小的服務器節點.
7.AvailabilityFilteringRule:過濾掉因為一直連接失敗而被標記為circuit tripped的服務節點和那些高並發的服務節點(active connections超過配置值
https://www.cnblogs.com/jsccc520/p/12075547.html