zoukankan      html  css  js  c++  java
  • SpringCloud+Eureka+Feign+Ribbon+zuul的简化搭建流程和CRUD练习

    环境: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("/optionData.do")
         public List<Map<String, Object>> optionData();


    @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>> optionData() {
              Map<String, Object> map= new HashMap<>();
              List<Map<String, Object>> list=new ArrayList<>();
              map.put("msg","provider findAllUser error");
              list.add(map);
             return list;
         }

    @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.1启动项 ZuulApplication

    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

    转:https://www.cnblogs.com/zhaozhitong/p/12095566.html

    optionData
  • 相关阅读:
    内置函数二
    通信的几个程序
    TCP协议和UDP协议
    异常处理
    logging模块
    网络编程一些概念
    hashlib
    序列化模块
    time,sys,os模块
    random模块
  • 原文地址:https://www.cnblogs.com/smallfa/p/13398437.html
Copyright © 2011-2022 走看看