使用Feign实现服务的消费者
我们在第7章已经将天气预报系统的所有功能都拆分为微服务。其中,也遗留了三个“TODO”项。
- 天气数据采集微服务在天气数据同步任务中,依赖于城市数据API微服务。
- 天气预报微服务查询天气信息,依赖于天气数据API微服务。
- 天气预报微服务提供的城市列表,依赖于城市数据API微服务。
这三个“TODO”项都需要调用外部系统的API。在本节我们将通过使用Feign来实现调用外部的RESTful服务。
天气数据采集微服务使用Feign
作为演示,我们将基于老的天气数据采集微服务 msa-weather-collection-eureka进行修改,成为新的具备Feign功能的微服务msa-weather-collection-eureka-feign。
1.项目配置
为了使用Feign,在 build.gradle文件中增加如下配置。
代码语言:javascript复制dependencies i
/l ...
//添加Spring Cloud Starter OpenFeign依赖
compile( 'org.springframework.cloud:spring-cloud-starter-openfeign')
}
2.启用Feign
要启用Feign,在应用的根目录的Application类上添加 org.springframework.cloud.netflix.fcign.EnableFeignClients注解即可。
代码语言:javascript复制package com.waylau.spring.cloud.weather;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscovery
Client;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
*主应用程序.
*
*@since 1.o.0 2017年11月05日
* @author <a href="https://waylau.com">Way Lau</a>
*/
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class Application{
public static void main(String [] args) {
SpringApplication.run(Application.class, args);
}
3.修改WeatherDataSyncJob
老的方法是伪造了一个城市数据。
代码语言:javascript复制List<City> cityList =null;
try{
//TODO调用城市数据API
cityList = new ArrayList<>();
City city = new City();
city.setCityId("101280601");
cityList.add(city);
}catch(Exception e){
logger.error("获取城市信息异常!",e);
throw new RuntimeException("获取城市信息异常!",e);
}
这里,我们将使用Feign来从城市数据API微服务msa-weather-city-cureka中获取城市的信息。
首先,我们要定义一个Feign客户端CityClient。
代码语言:javascript复制package com.waylau.spring.cloud.weather.service;
import java.util.List;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import com.waylau.spring.cloud.weather.vo.City;
/*★
*访问城市信息的客户端.
*
*@since 1.0.0 2017年11月5日
* @author <a href="https://waylau.com">Way Lau</a>
*/
@FeignClient("msa-weather-city-eureka")
public interface CityClient {
@GetMapping("/cities")
List<City> listCity() throws Exception;
}
CityClient在@FeignClient注解中指定了需要访问的应用的名称。
其次,我们在需要获取外部服务的WeatherDataSyncJob类中,使用CityClient接口即可。
代码语言:javascript复制package com.waylau.spring.cloud.weather.job;
import java.util.List;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j·LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import com.waylau.spring.cloud.weather.service.CityClient;
import com.waylau.spring.cloud.weather.service.WeatherDataCollection
Service;
import com.waylau.spring.cloud.weather.vo.City;
/**
*天气数据同步任务.
*
*@since 1.o.o 2017年10月29日
* @author <a href="https://waylau.com">Way Lau</a>
*/
public class WeatherDataSyncJob extends QuartzJobBean
private final static Logger logger = LoggerFactory.getLogger(Weather
DataSyncJob .class);
Autowired
private WeatherDataCollectionService weatherDataCollectionService;
Autowired
private CityClient cityClient;
@override
protected void executeInternal (JobExecutionContext context) throws
JobExecutionException {
logger.info("Start天气数据同步任务");
//由城市数据API微服务来提供数据
List<City> cityList = null;
try {
//调用城市数据API
cityList = cityClient.listCity();
]catch(Exception e)
logger.error("获取城市信息异常!",e);
throw new RuntimeException("获取城市信息异常!",e);
}
for (City city :cityList){
String cityId= city.getcityId();
logger.info("天气数据同步任务中,cityid:" cityId);
//根据城市ID同步天气数据
weatherDataCollectionService.syncDataByCityId(cityId);
logger.info("End 天气数据同步任务");
}
}
4.修改项目配置
最后,修改application.properties。将其修改为如下配置。
代码语言:javascript复制spring.application.name: msa-weather-collection-eureka-feign
eureka.client.serviceUrl.defaultZone:http://localhost:8761/eureka/
feign.client.config.feignName.connectTimeout:5000
feign.client.config.feignName.readTimeout:5000
天气预报微服务使用Feign
的具备Feign功能的微服务 msa-weather-report-eureka-feign。
1.项目配置
为了使用Feign,在 build.gradle文件中增加如下配置。
代码语言:javascript复制dependencies {
// ...
作为演示,我们将基于老的天气数据采集微服务msa-weather-report-cureka进行修改,成为新
//添加Spring Cloud starter OpenFeign依赖
compile('org.springframework.cloud:spring-cloud-starter-openfeign')
)
2.启用Feign
要启用Feign,在应用的根目录的Application类上添加 org.springframework.cloud.netflix.feign.EnableFeignClients注解即可。
代码语言:javascript复制package com.waylau.spring.cloud.weather;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscovery
Client;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
**
*主应用程序.
*
*@since 1.o.0 2017年11月05日
* author <a href="https://waylau.com">Way Lau</a>
*/
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class Application{
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
3.定义Feign客户端
首先,我们要定义一个Feign客户端CityClient,来从城市数据API微服务msa-weather-city-eureka中获取城市的信息。
代码语言:javascript复制package com.waylau.spring.cloud.weather.service;
import java.util.List;
import org.springframework.cloud.netflix.feign.Eeignclient;
import org.springframework.web.bind.annotation.GetMapping;
import com.waylau.spring.cloud.weather.vo.City;
/**
*访问城市信息的客户端.
*
@since 1.o.0 2017年11月5日
author <a href="https://waylau.com">Way Lau</a>
*/
@FeignClient( "msa-weather-city-eureka")
public interface CityClient{
@GetMapping("/cities")
List<City> listCity()throws Exception;
}
其次,我们再定义一个Feign客户端WeatherDataClient,来从天气数据API微服务msa-weather-data-eureka中获取天气的数据。
代码语言:javascript复制package com.waylau.spring.cloud.weather.service;
import org.springframework.cloud.netflix.feign.FeignClient;
import com.waylau.spring.cloud.weather.vo.WeatherResponse;
★*
*访问天气数据的客户端.
*
*@since 1.o.02017年11月5日
*@author <a href="https://waylau.com">Way Lau/a>
*/
FeignClient( "msa-weather-data-eureka")
public interface WeatherDataclient {
/**
*根据城市ID查询天气数据
*
*@param cityId
*@return
*/
@GetMapping("/weather/cityId/{cityId}")
WeatherResponse getDataByCityId(@PathVariable("cityId") String
cityId);
}
4.修改天气预报服务
修改天气预报服务WeatherReportServicelmpl,将原有的仿造的数据改为从Feign客户端获取天气数据API微服务提供的数据。
代码语言:javascript复制package com.waylau.spring.cloud.weather.service;
import org.springframework.beans.factory.annotation.Autowired;
irmport org.springframework.stereotype.Service;
import com.waylau.spring.cloud.weather.vo.Weather;
import com.waylau.spring.cloud.weather.vo.WeatherResponse;
**
*天气预报服务.
*
*@since 1.o.0 2017年11月05日
*@author <a href="https://waylau.com">Way Lau</a>
*/
@service
public class WeatherReportServiceimpl implements WeatherReportService{
Autowired
private WeatherDataClient weatherDataClient;
@override
public Weather getDataByCityId(String cityId)
//由天气数据AP工微服务来提供数据
WeatherResponse response = weatherDataclient.getDataByCityId
(cityId);
return response.getData(;
}
5.修改天气预报控制器
修改天气预报控制器WeatherReportController,将原有的伪造的城市数据改为由CityClient来获
取城市数据API微服务中的城市数据。
代码语言:javascript复制package com.waylau.spring.cloud.weather.controller;
import java.util.List;
import org.slf4j-Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
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.servlet.ModelAndView;
import com.waylau.spring.cloud.weather.service.CityClient;
import com.waylau.spring.cloud.weather.service.WeatherReportService;
import com.waylau.spring.cloud.weather.vo.City;
/**
*天气预报API.
*
*@since 1.0.0 2017年10月29日
@author <a href="https://waylau.com" >Way Lau</a>
*/
RestController
@RequestMapping("/report")
public class WeatherReportController {
private final static Logger logger = LoggerFactory.getLogger(Weather
ReportController.class);
@Autowired
private CityClient cityClient;
@Autowired
private WeatherReportService weatherReportService;
@GetMapping("/cityId/{cityId} ")
public ModelAndView getReportByCityId (@PathVariable ("cityId") String
cityId, Model model) throws Exception {
//由城市数据API微服务来提供数据
List<City> cityList =null;
try{
//调用城市数据API
cityList=cityClient.listCity();
}catch(Exception e)
logger.error("获取城市信息异常!",e);
throw new RuntimeException("获取城市信息异常!",e);
}
model.addAttribute("title","老卫的天气预报");
model.addAttribute("cityld",cityId);
model.addAttribute("cityList",cityList);
model.addAttribute ("report", weatherReportService.getDataBy
CityId(cityId));
return new ModelAndView("weather/report", "reportModel",
model);
}
6.修改项目配置
最后,修改application.properties。将其修改为如下配置。
代码语言:javascript复制#热部署静态文件
spring.thymeleaf.cache=false
spring.application.name: msa-weather-report-eureka-feign
eureka.client.serviceUrl.defaultZone: http://localhost:8761/eureka/
feign.client.config.feignName.connectTimeout:5000
feign.client.config.feignName.readTimeout:5000
源码
本节示例所涉及的源码,见 micro-weather-eureka-server、msa-weather-data-eureka和msa-weather-city-eureka,以及msa-weather-collection-eureka-feign和 msa-weather-report-eureka-feign。
本篇文章内容给大家讲解的是使用Feign实现服务的消费者
- 下篇文章给大家讲解实现服务的负载均衡及高可用;
- 觉得文章不错的朋友可以转发此文关注小编;
- 感谢大家的支持
本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。