微服务之Ribbon客户端负载均衡,Http远程调用服务,Feign接口方式调用远程服务

1.先单独搭建一个微服务,这个微服务不需要配置文件,专门用来存放实体类与一些公用的配置类

微服务之Ribbon客户端负载均衡,Http远程调用服务,Feign接口方式调用远程服务_第1张图片

package cn.xrj.springcloud.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Qcpage extends Model implements Serializable{
    /**
     * 主键id
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /**
     * 职位
     */
    private String job;

    /**
     * 公司
     */
    private String company;

    /**
     * 工作地点
     */
    private String place;

    /**
     * 薪水
     */
    private String salar;

    /**
     * 发布时间
     */
    private String data;

    /**
     * 标记数据来自或存储到哪个数据库
     */
    private String dbsource;
}

注意:@AllArgsConstructor注解表示全参构造方法,@NoArgsConstructor注解表示无参构造方法,@Accessors(chain = true)注解表示允许链式写法。dbsource属性用于标记数据库(微服务架构一般为分布式系统,所以记录数据的来源与去处),后面测试负载均衡时可见效果。

JobInfoService接口与ServiceFallBackFactory实现类用于Feign远程调用与服务降级时使用,目前不说明。

2.服务提供者

pom:



    4.0.0
    
        cn.microsoft
        springcloud
        1.0-SNAPSHOT
    
    cn.xrj.springcloud
    springcloud-provider-jobinfo-8001
    0.0.1-SNAPSHOT
    springcloud-provider-jobinfo-8001

    
        1.8
    

    
        
        
            org.springframework.cloud
            spring-cloud-starter-eureka
            1.4.6.RELEASE
        

        
        
            org.springframework.boot
            spring-boot-starter-actuator
        

        
        
            cn.xrj.springcoud
            springcloud-api
            0.0.1-SNAPSHOT
        
        
            org.springframework.boot
            spring-boot-starter-jdbc
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            com.baomidou
            mybatis-plus-boot-starter
        

        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        
        
            mysql
            mysql-connector-java
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
            com.baomidou
            mybatis-plus-generator
        

        
            org.apache.velocity
            velocity-engine-core
        
        
            junit
            junit
            test
        
    

    
        
            
                src/main/java
                
                
                    **/*.xml
                
            
            
            
                src/main/resources
                
                    **/*.yml
                    **/*.properties
                    **/*.xml
                    **/*.*
                
            
        
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


配置文件:

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: 199654
    url: jdbc:mysql://localhost:3306/pachong?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
  application:
    name: springcloud-provider-jobinfo //微服务名

mybatis-plus: //mybatis-plus配置
  mapper-locations: classpath:cn/xrj/springcloud/mapper/*/*.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  type-aliases-package: cn.xrj.springcloud.pojo

server:  
  port: 8001  //端口号
eureka:
  client:
    service-url:
      defaultZone://需要注册到的eureka集群 http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: springcloud-provider-jobinfo:8001 //微服务实例名
    hostname: localhost
    prefer-ip-address: true  //是否显示IP地址

info: //这里配置,当点击eureka里的微服务时,跳到相应的info界面,而保护出现error页面
  app.name: springcloud-provider-jobinfo
  company.name: richinfo
  author.name: xingrenjie

微服务之Ribbon客户端负载均衡,Http远程调用服务,Feign接口方式调用远程服务_第2张图片

Controller层:

package cn.xrj.springcloud.controller;



import cn.xrj.springcloud.service.QcpageService;
import cn.xrj.springcloud.pojo.Qcpage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 

* 51job招聘信息表 前端控制器 *

* * @author xrj * @since 2019-12-13 */ @RestController public class QcpageProviderController { @Autowired QcpageService qcpageService; @Autowired DiscoveryClient client; @GetMapping("/qcpage/getAll") public List getAll(){ List list= qcpageService.list(); return list; } @GetMapping("/qcpage/getById/{id}") public Qcpage getById(@PathVariable("id")Integer id){ Qcpage qcpage=qcpageService.getById(id); return qcpage; } @DeleteMapping("/qcpage/deleteById/{id}") public boolean deleteById(@PathVariable("id")Integer id){ boolean flag=qcpageService.removeById(id); return flag; } //获取注册进来的微服务,可以获得一些微服务信息,服务发现 @GetMapping("/qcpage/getservice") public Object getService(){ List service=client.getServices(); System.out.println("service:"+service); List instances=client.getInstances("springcloud-provider-jobinfo"); for (ServiceInstance instance : instances) { System.out.println("serviceId:"+instance.getServiceId()); System.out.println("InstanceId:"+instance.getInstanceId()); System.out.println("host:"+instance.getHost()); System.out.println("port:"+instance.getPort()); } return this.client; } }

启动类:

@SpringBootApplication
@MapperScan("cn.xrj.springcloud.mapper")
@EnableEurekaClient
@EnableDiscoveryClient //服务发现~
public class SpringcloudProviderJobinfo8001Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringcloudProviderJobinfo8001Application.class, args);
    }

}

其中:@EnableEurekaClient注解开启eureka客户端,@EnableDiscoveryClient注解开启服务发现,服务提供者跟普通的controller没什么区别!!,如果做集群,那么复制一份即可,如果不同服务器则端口需改!!!

3.服务消费者,开启Ribbon负载均衡,http远程调用服务

微服务之Ribbon客户端负载均衡,Http远程调用服务,Feign接口方式调用远程服务_第3张图片

pom:



    4.0.0
    
        cn.microsoft
        springcloud
        1.0-SNAPSHOT
    
    cn.xrj.springcloud
    springcloud-consumer-jobinfo-80
    0.0.1-SNAPSHOT
    springcloud-consumer-jobinfo-80

    
        1.8
    

    
        
            org.springframework.cloud
            spring-cloud-starter-eureka
            1.4.6.RELEASE
        
        
            org.springframework.cloud
            spring-cloud-starter-ribbon
        
        
            cn.xrj.springcoud
            springcloud-api
            0.0.1-SNAPSHOT
        
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-devtools
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            junit
            junit
            test
        
    

    
        
            
                src/main/java
                
                
                    **/*.xml
                
            
            
            
                src/main/resources
                
                    **/*.yml
                    **/*.properties
                    **/*.xml
                    **/*.*
                
            
        
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


配置文件:

server:
  port: 80

eureka:
  client:
    register-with-eureka: false
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

Controller层:

package cn.xrj.springcloud.controller;

import cn.xrj.springcloud.pojo.Qcpage;
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;

@RestController
public class QcpageConsumerController {
    @Autowired
    private RestTemplate restTemplate;
    //以下注释常量为未使用ribbon负载均衡时配置的,只能调用某个微服务的一个实例,真实场景是某个微服务做了集群配置,所以此方法不用
//    private static final String PRIFIX="http://localhost:8001";

    //开启负载均衡后,主机名与端口号使用服务名代替,在调用时,则轮询调用某微服务下所有集群实例
    private static final String PRIFIX="http://SPRINGCLOUD-PROVIDER-JOBINFO";

    @RequestMapping("/consumer/jobinfo/getById/{id}")
    public Qcpage getById(@PathVariable("id")Integer id){
        return restTemplate.getForObject(PRIFIX+"/qcpage/getById/"+id,Qcpage.class);
    }

    @RequestMapping("/consumer/jobinfo/getAll")
    public List getAll(){
        return restTemplate.getForObject(PRIFIX+"/qcpage/getAll",List.class);
    }

    @RequestMapping("/consumer/jobinfo/deleteById/{id}")
    public void deleteById(@PathVariable("id")Integer id){
         restTemplate.delete(PRIFIX+"/qcpage/deleteById/{id}",id);
    }
}

Ribbon配置及开启(默认配置轮询机制,可自定义配置,后续加上):

@Configuration
public class ConfigBean {
    @Bean
    @LoadBalanced //此注解开启请求时使用ribbon负载均衡
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

启动类:

@SpringBootApplication( exclude= {DataSourceAutoConfiguration.class})配置此属性为了避免自动配置数据源,因为此服务为消费者,本身不需要数据源
@EnableEurekaClient//开启eureka客户端
public class SpringcloudConsumerJobinfo80Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringcloudConsumerJobinfo80Application.class, args);
    }

}

如此,启动eureka集群,启动服务提供者和消费者,访问消费者接口,则会远程调用服务提供者接口获取数据,因为开启了ribbon客户端负载均衡,所以,获取的数据的dbsource属性会有不同的值,表示来自不同的数据库。

4.服务消费者改用Feign接口方式调用服务(更符合面向接口编程,底层集成了Ribbon来实现负载均衡)

消费者的pom文件和api服务里导入依赖:


            org.springframework.cloud
            spring-cloud-starter-feign
            1.4.6.RELEASE
        

由于底层集成了ribbon,所以ribbon还是要开启,配置简单。

然后在上面搭建的api这个微服务里新建service包,里面新建一个接口:

package cn.xrj.springcloud.service;

import cn.xrj.springcloud.pojo.Qcpage;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.List;

@FeignClient(value = "springcloud-provider-jobinfo")
@Component
public interface JobInfoService {
    @GetMapping("/qcpage/getAll")
    List getAll();

    @GetMapping("/qcpage/getById/{id}")
    Qcpage getById(@PathVariable("id")Integer id);

    @DeleteMapping("/qcpage/deleteById/{id}")
    boolean deleteById(@PathVariable("id")Integer id);
}

此接口使用@FeignClient(value = "springcloud-provider-jobinfo")注解,表示此接口是一个Feign客户端,并调用的服务为名为springcloud-provider-jobinfo的微服务,里面包含三个抽象方法,对应了springcloud-provider-jobinfo微服务下的三个接口。注意,方法名可以不同,但返回值和参数类型必须相同,且接口路径和请求方式必须一一对应,用于标识哪个方法对应哪个接口。

消费者controller调用:

package cn.xrj.springcloud.controller;

import cn.xrj.springcloud.pojo.Qcpage;
import cn.xrj.springcloud.service.JobInfoService;
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 java.util.List;

@RestController
public class QcpageConsumerController {
    @Autowired
    JobInfoService jobInfoService;

    @RequestMapping("/consumer/jobinfo/getById/{id}")
    public Qcpage getById(@PathVariable("id")Integer id){
        return jobInfoService.getById(id);
    }

    @RequestMapping("/consumer/jobinfo/getAll")
    public List getAll(){
        return jobInfoService.getAll();
    }

    @RequestMapping("/consumer/jobinfo/deleteById/{id}")
    public boolean deleteById(@PathVariable("id")Integer id){
         return jobInfoService.deleteById(id);
    }
}

到此,feign远程调用服务结束,是不是更加符合面向接口编程的思想!!也更方便实用!也很容易理解。

你可能感兴趣的:(微服务之Ribbon客户端负载均衡,Http远程调用服务,Feign接口方式调用远程服务)