Spring Cloud 提供Feign客户端调用Eureka注册接口
Spring Cloud 提供Feign客户端调用Eureka注册接口
海蛎子大呲花 发表于9个月前
Spring Cloud 提供Feign客户端调用Eureka注册接口
  • 发表于 9个月前
  • 阅读 436
  • 收藏 0
  • 点赞 0
  • 评论 0

华为云·免费上云实践>>>   

摘要: 【引用】Spring Cloud Netflix是Spring Cloud的子项目之一,主要内容是对Netflix公司一系列开源产品的包装,它为Spring Boot应用提供了自配置的Netflix OSS整合。通过一些简单的注解,开发者就可以快速的在应用中配置一下常用模块并构建庞大的分布式系统。它主要提供的模块包括:服务发现(Eureka),断路器(Hystrix),智能路有(Zuul),客户端负载均衡(Ribbon)等。
server.port=1111
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/

【引用翟永超个人博客对Feign定义】Spring Cloud Netflix子项目中,Feign是一个声明式的Web Service客户端,它使得编写Web Serivce客户端变得更加简单。我们只需要使用Feign来创建一个接口并用注解来配置它既可完成。它具备可插拔的注解支持,包括Feign注解和JAX-RS注解。Feign也支持可插拔的编码器和解码器。Spring Cloud为Feign增加了对Spring MVC注解的支持,还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。

Eureka模块主要是服务发现模块,提供了一个服务注册中心,注册者在Eureka上发布接口,消费者在Eureka上进行接口调用消费,和dubbo的思路很像。Feign调用起来更为方便,可以很轻便的通过SpringMVC的方式调用restful的接口。并且结合了Ribbon和Eureka,做到了客户端的负载均衡,假如有两个端口不同的服务启动,接口同时注册在Spring Eureka上,并起同样的名字服务,客户端调用服务时两次,该服务下两个端口下的接口会分别被调用一次,客户端自动去做了负载均衡这件事。

该案例实现,可以建立三个工程,三个工程分别是eureka-feign(客户端)、Register-service(服务注册中心)、compute-service(服务发布),其中compute-service可以用两个端口分别启动一次,测试负载均衡效果。

端口:

     Register-service:1111

     compute-service:2222/2223

     eureka-feign:3333   

Register-service工程

该工程需要的依赖主要是

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>

application.properites配置文件配置:

server.port=1111
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/

声明了端口,以及注册中心的端口和位置。

启动类:

/**
 * @author zhangtuo
 * @Date 2017/2/17
 */
@EnableEurekaServer//启动一个服务注册中心提供给其他应用进行对话
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }
}

 

compute-service工程

pom依赖:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.39</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>0.2.26</version>
        </dependency>

        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>

controller层用来提供外部接口。application.properties配置文件配置,指定了刚才启动的注册中心位置。和注册的服务名字为compute-service。

spring.application.name=compute-service

server.port=2222
# 指定注册服务中心
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

启动类实现:

/**
 * @author zhangtuo
 * @Date 2017/2/17
 */
@EnableDiscoveryClient
@SpringBootApplication
public class ComputeServiceApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(ComputeServiceApplication.class).web(true).run(args);
    }

}

在主类中通过加上@EnableDiscoveryClient注解,该注解能激活Eureka中的DiscoveryClient实现,才能实现Controller中对服务信息的输出。

控制层提供的接口CameraInfoController:

/**
 * @author zhangtuo
 * @Date 2017/2/17
 */
@RestController
@RequestMapping("cameraInfo")
public class CameraInfoController {

    private final Logger LOGGER = Logger.getLogger(getClass());

    @Autowired
    private DiscoveryClient discoveryClient;//激活Eureka中的DiscoveryClient实现

    @Autowired
    private CameraService cameraService;

    /**
     * 注册服务返回的数据以String字符串的json返回
     * @return
     */
    @RequestMapping(method = RequestMethod.GET)
    public String findCameraInfos() {
        ServiceInstance serviceInstance = discoveryClient.getLocalServiceInstance();//获取Discoveryclient,打印注册中心的log
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("host:" + serviceInstance.getHost() + ", service id" + serviceInstance.getServiceId());
        }
        List<CameraInfo> cameraInfos = cameraService.findCameraInfos();
        /**
         * 转换json字符串
         */
        JSONArray listArray = JSONArray.fromObject(cameraInfos);
        String result = listArray.toString();
        return result;
    }
}

 

Eureka-feign工程

pom依赖:

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-feign</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</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>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>net.sf.json-lib</groupId>
			<artifactId>json-lib</artifactId>
			<version>2.4</version>
			<classifier>jdk15</classifier>
		</dependency>

		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger2</artifactId>
			<version>2.2.2</version>
		</dependency>
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger-ui</artifactId>
			<version>2.2.2</version>
		</dependency>

启动类:

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients//启动Feign客户端注解
public class FeignApplication {

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

}

声明要调用的接口interface:

/**
 * @author zhangtuo
 * @Date 2017/2/17
 */
@FeignClient("compute-service")
public interface CameraInfoClient {

    @RequestMapping(value = "cameraInfo", method = RequestMethod.GET)
    public String findCameraInfos();

}

Feign用Swagger2来测试Restful接口调用,因此在控制层对Controller进行了api注解:

/**
 * @author zhangtuo
 * @Date 2017/2/17
 */
@RestController
@RequestMapping("cameraInfo")
public class CameraInfoController {

    private static final Logger LOGGER = Logger.getLogger(CameraInfoController.class);

    @Autowired
    private CameraInfoClient cameraInfoClient;

    @ApiOperation(value="获取摄像机节点列表", notes="")
    @RequestMapping(method = RequestMethod.GET)
    public ResponseEntity<String> findCameraInfos() {
        try {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.info("find CameraInfo");
            }
            String result = cameraInfoClient.findCameraInfos();
            if (result != null) {
                return ResponseEntity.ok(result);
            } else {
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
            }
        } catch (Exception e) {
            LOGGER.error("get CameraInfo is failed!" + e);
        }
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
    }

}

启动后,会在localhost:1111上看到注册的服务方和消费方

这里只启动了一个端口的服务接口,同理,可以启动几个端口的服务,客户端调用做到负载均衡。

通过测试发现成功调用接口。

在compute-service的控制台上log也打印了调用情况:

共有 人打赏支持
粉丝 5
博文 44
码字总数 16098
×
海蛎子大呲花
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: