SpringCloud+Eureka+Feign+Ribbon的简化搭建流程和CRUD练习
个人微信公众号:程序猿的月光宝盒
[toc]
# 环境: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
/**
 * 是consumer调用provider(需要指定provider的名字)
 * 请求的清单列表:规定调用地址、参数、返回值
 */
@FeignClient(name = "provider")
public interface CenterFeign {
    @GetMapping("/optionData.do")
    public List<Map<String, Object>> optionData();
}
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
4.6在启动类上添加注解
ConsumerApplication.java
//开启Feign客户端
@EnableFeignClients
//开启eureka客户端
@EnableEurekaClient
@SpringBootApplication
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}
5.用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超过配置值)
SpringCloud+Eureka+Feign+Ribbon的简化搭建流程和CRUD练习的更多相关文章
- SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]
		
目录 前提:本篇是基于 SpringCloud+Eureka+Feign+Ribbon的简化搭建流程和CRUD练习[1] 的修改与拓展 1.修改consumer的CenterFeign.java,把返 ...
 - SpringCloud+Eureka+Feign+Ribbon+zuul的简化搭建流程和CRUD练习
		
环境:win10--idea2019--jdk8 1.搭建Eureka服务模块 1.1 新建eureka服务模块(Sping Initializr) 取名为eureka-server,并添加如下Dep ...
 - springCloud——Eureka、Ribbon理解
		
一. 服务注册中心.服务提供者.服务消费者 如何通信? 客户端: 应用主类中配置@EnableDiscoveryClient application.properties中配置defaultZone指 ...
 - springcloud微服务实战:Eureka+Zuul+Feign/Ribbon+Hystrix Turbine+SpringConfig+sleuth+zipkin
		
相信现在已经有很多小伙伴已经或者准备使用springcloud微服务了,接下来为大家搭建一个微服务框架,后期可以自己进行扩展.会提供一个小案例: 服务提供者和服务消费者 ,消费者会调用提供者的服务,新 ...
 - SpringCloud基础概念学习笔记(Eureka、Ribbon、Feign、Zuul)
		
SpringCloud基础概念学习笔记(Eureka.Ribbon.Feign.Zuul) SpringCloud入门 参考: https://springcloud.cc/spring-cloud- ...
 - SpringCloud学习笔记(六):Feign+Ribbon负载均衡
		
简介 官网解释: http://projects.spring.io/spring-cloud/spring-cloud.html#spring-cloud-feign Feign是一个声明式WebS ...
 - springcloud微服务实战:Eureka+Zuul+Ribbon+Hystrix+SpringConfig
		
原文地址:http://blog.csdn.net/yp090416/article/details/78017552 springcloud微服务实战:Eureka+Zuul+Ribbon+Hyst ...
 - springCloud系列教程01:Eureka 注册中心集群搭建
		
springCloud系列教程包含如下内容: springCloud系列教程01:Eureka 注册中心集群搭建 springCloud系列教程02:ConfigServer 配置中心server搭建 ...
 - SpringCloud系列五:Ribbon 负载均衡(Ribbon 基本使用、Ribbon 负载均衡、自定义 Ribbon 配置、禁用 Eureka 实现 Ribbon 调用)
		
1.概念:Ribbon 负载均衡 2.具体内容 现在所有的服务已经通过了 Eureka 进行了注册,那么使用 Eureka 注册的目的是希望所有的服务都统一归属到 Eureka 之中进 行处理,但是现 ...
 
随机推荐
- 联想Y7000,I5-9300H+Nvidia GTX 1050, kali linux的nvidia显卡驱动安装
			
转载自,Linux安装NVIDIA显卡驱动的正确姿势 https://blog.csdn.net/wf19930209/article/details/81877822#NVIDIA_173 ,主要用 ...
 - centos7关闭默认firewall,启用iptables
			
CentOS 7.0默认使用"firewall"防火墙 一:关闭firewall1.直接关闭防火墙systemctl stop firewalld.service 2.禁止fire ...
 - linux字符集修改
			
首先介绍一下变量. 1.变量类型:本地变量.环境变量.局部变量.特殊变量(内置).参数变量.只读变量. 2.bash的配置文件:profile类和bashrc类 profile类:为交互式登录的she ...
 - YoungLots Team - Record a software installation
			
一.写在最前 本文记录安装或配置以下软件或环境的过程:VScode,Xampp,navicat,PHP,html,CSS,SQL,JavaScript. 作者使用的环境:浏览器:Google Chro ...
 - c语言l博客作业02
			
问题 答案 这个作业属于哪个课程 C语言程序设计l 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/SE2019-2/homework/8687 我在这个 ...
 - OC中ARC forbids explicit message send of release错误
			
在ios编程中,如果成员变量为对象,我们需要对成员变量内存管理,否则,会造成内存泄露.即我们要对成员变量进行手动的内存释放. 很显然,是ARC的问题. 错误原因:在创建工程的时候点选了“Use Aut ...
 - PHP计算两组经纬度坐标之间的距离
			
定义π define('PI',3.1415926535898); define('EARTH_RADIUS',6378.137); 计算两组经纬度坐标 之间的距离 /** * 计算两组经纬度坐标 之 ...
 - 引用公共页面的js函数报错
			
对于网站来说很多页面之间都有着大量的共享模块,如页头,页脚和用户栏等.很多时候为了方便.省事,我们在公共模块写函数,然后在别的页面里调用.但我们在引用公共的js函数时,有些可以引用,有些却报错:这是因 ...
 - Leecode_137_singleNumberII
			
参考: http://blog.csdn.net/jocyln9026/article/details/19397477
 - 区块链学习笔记:DAY05 如何使用公有云区块链服务
			
这是最后一节课了,主要讲华为云在云区块链提供的服务,如何基于华为云BCS来构建应用 先来个简单的比喻: 1.有关BaaS的范围定义 包含物理主机.虚拟主机.容器服务.区块链.智能合约和服务 2.华为云 ...