Spring Cloud学习笔记17——天气预报系统微服务使用 Feign

回顾遗留的三个TODO

  • 数据采集微服务在天气数据同步任务中,依赖于城市数据API微服务
  • 天气预报微服务查询天气信息,依赖于天气数据API微服务
  • 天气预报微服务提供的城市列表,依赖于城市数据API微服务

天气预报系统微服务使用Feign

在这里插入图片描述

msa-weather-collection-eureka-feign

创建项目

复制之前的msa-weather-collection-eureka项目,将副本改名为msa-weather-collection-eureka-feign
在这里插入图片描述

修改源码

修改build.gradle配置,添加Feign依赖:

//依赖关系
dependencies {

    //该依赖用于编译阶段
	compile('org.springframework.boot:spring-boot-starter-web')
	
	//HttpClient
	compile('org.apache.httpcomponents:httpclient:4.5.6')

    //Redis
    compile('org.springframework.boot:spring-boot-starter-data-redis')

    //Quartz
    compile('org.springframework.boot:spring-boot-starter-quartz')

    //Eureka Client
    compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')

    //Feign
    compile('org.springframework.cloud:spring-cloud-starter-openfeign:2.0.0.M3')

    //该依赖用于测试阶段
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

修改com.study.spring.cloud.weather包下的Application类,加入@EnableFeignClients注解:

package com.study.spring.cloud.weather;

		import org.springframework.boot.SpringApplication;
		import org.springframework.boot.autoconfigure.SpringBootApplication;
		import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
		import org.springframework.cloud.netflix.feign.EnableFeignClients;

/*
 * @SpringBootApplication注解声明Spring Boot应用
 * 作用等同于@Configuration, @EnableAutoConfiguration, @ComponentScan,
 * 简化Spring配置
 */
@SpringBootApplication
//启用可发现的客户端
@EnableDiscoveryClient
//启用Feign
@EnableFeignClients
//Application类一定要处于整个工程的根目录下,这样它才能根据配置去扫描子节点下的Spring的Bean
public class Application {

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

com.study.spring.cloud.weather.service包下新建接口CityClient

package com.study.spring.cloud.weather.service;

import com.study.spring.cloud.weather.vo.City;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

@FeignClient("msa-weather-city-eureka")
public interface CityClient {

	@GetMapping("/cities")
	List<City> listCity() throws Exception;
}

修改com.study.spring.cloud.weather.job包下的WeatherDataSyncJob类:

package com.study.spring.cloud.weather.job;

import com.study.spring.cloud.weather.service.CityClient;
import com.study.spring.cloud.weather.service.WeatherDataCollectionService;
import com.study.spring.cloud.weather.vo.City;
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 java.util.List;

public class WeatherDataSyncJob extends QuartzJobBean {

	//在应用中添加日志
	private final static Logger logger=LoggerFactory.getLogger(WeatherDataCollectionService.class);

	@Autowired
	private WeatherDataCollectionService weatherDataCollectionService;

	@Autowired
	private CityClient cityClient;

	@Override
	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {

		logger.info("Weather Data Sync Job. Start!");

		//获取城市列表
		List<City> cityList=null;

		try {
			//由城市数据API微服务来提供数据
			cityList = cityClient.listCity();
		} catch (Exception e) {
			logger.error("Exception!",e);
		}

		//遍历城市id获取天气
		for(City city:cityList){
			String cityId=city.getCityId();
			logger.info("Weather Data Sync Job, cityId:"+cityId);

			weatherDataCollectionService.syncDataByCityId(cityId);
		}

		logger.info("Weather Data Sync Job. End!");
	}
}

修改application.properties配置文件:

#应用名称
spring.application.name=msa-weather-collection-eureka-feign

#注册服务器的URL
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

#请求服务时的超时时间
feign.client.config.feignName.connect-timeout=5000

#读数据时的超时时间
feign.client.config.feignName.read-timeout=5000

msa-weather-report-eureka-feign

创建项目

复制之前的msa-weather-report-eureka项目,将副本改名为msa-weather-report-eureka-feign
在这里插入图片描述

修改源码

修改build.gradle配置,添加Feign依赖:

//依赖关系
dependencies {

    //该依赖用于编译阶段
	compile('org.springframework.boot:spring-boot-starter-web')

    //添加Spring Boot Thymeleaf Starter的依赖
    compile('org.springframework.boot:spring-boot-starter-thymeleaf')

    //Eureka Client
    compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')

    //Feign
    compile('org.springframework.cloud:spring-cloud-starter-openfeign:2.0.0.M3')


    //该依赖用于测试阶段
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

修改com.study.spring.cloud.weather包下的Application类,加入@EnableFeignClients注解:

package com.study.spring.cloud.weather;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;

/*
 * @SpringBootApplication注解声明Spring Boot应用
 * 作用等同于@Configuration, @EnableAutoConfiguration, @ComponentScan,
 * 简化Spring配置
*/
@SpringBootApplication
//启用可发现的客户端
@EnableDiscoveryClient
//启用Feign
@EnableFeignClients
//Application类一定要处于整个工程的根目录下,这样它才能根据配置去扫描子节点下的Spring的Bean
public class Application {

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

com.study.spring.cloud.weather.service包下新建接口CityClient

package com.study.spring.cloud.weather.service;

import com.study.spring.cloud.weather.vo.City;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

@FeignClient("msa-weather-city-eureka")
public interface CityClient {

	@GetMapping("/cities")
	List<City> listCity() throws Exception;
}

com.study.spring.cloud.weather.service包下新建接口WeatherDataClient

package com.study.spring.cloud.weather.service;

import com.study.spring.cloud.weather.vo.WeatherResponse;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient("msa-weather-data-eureka")
public interface WeatherDataClient {

	@GetMapping("/weather/cityId/{cityId}")
	WeatherResponse getDataByCityId(@PathVariable("cityId") String cityId);
}

修改com.study.spring.cloud.weather.service包下的WeatherReportServiceImpl类:

package com.study.spring.cloud.weather.service;

import com.study.spring.cloud.weather.vo.Weather;
import com.study.spring.cloud.weather.vo.WeatherResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class WeatherReportServiceImpl implements WeatherReportService {

	@Autowired
	private WeatherDataClient weatherDataClient;

	@Override
	public Weather getDataByCityId(String cityId) {
		
		//由天气数据API微服务来提供数据
		WeatherResponse resp=weatherDataClient.getDataByCityId(cityId);
		Weather data=resp.getData();
		return data;
	}
}

修改com.study.spring.cloud.weather.controller包下的WeatherReportController类:

package com.study.spring.cloud.weather.controller;

import com.study.spring.cloud.weather.service.CityClient;
import com.study.spring.cloud.weather.service.WeatherReportService;
import com.study.spring.cloud.weather.vo.City;
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 java.util.List;

@RestController
@RequestMapping("/report")
public class WeatherReportController {

	//在应用中添加日志
	private final static Logger logger=LoggerFactory.getLogger(WeatherReportController.class);

	@Autowired
	private WeatherReportService weatherReportService;

	@Autowired
	private CityClient cityClient;

	@GetMapping("/cityId/{cityId}")
	//@PathVariable:标识从路径中获取参数
	public ModelAndView getReportByCityId(@PathVariable("cityId") String cityId,Model model) throws Exception {

		//获取城市列表
		List<City> cityList=null;

		try {
			//由城市数据API微服务来提供数据
			cityList = cityClient.listCity();
		} catch (Exception e) {
			logger.error("Exception!",e);
		}

		model.addAttribute("title", "天气预报");
		model.addAttribute("cityId", cityId);
		model.addAttribute("cityList", cityList);
		model.addAttribute("report", weatherReportService.getDataByCityId(cityId));

		return new ModelAndView("weather/report","reportModel",model);
	}
	
}

修改application.properties配置文件:

#热部署静态文件
spring.thymeleaf.cache=false

#应用名称
spring.application.name=msa-weather-report-eureka-feign

#注册服务器的URL
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

#请求服务时的超时时间
feign.client.config.feignName.connect-timeout=5000

#读数据时的超时时间
feign.client.config.feignName.read-timeout=5000

运行微服务实例

注意要先运行Redis

java -jar micro-weather-eureka-server-1.0.0.jar --server.port=8761

java -jar msa-weather-collection-eureka-feign-1.0.0.jar --server.port=8081

java -jar msa-weather-collection-eureka-feign-1.0.0.jar --server.port=8082

java -jar msa-weather-data-eureka-1.0.0.jar --server.port=8083

java -jar msa-weather-data-eureka-1.0.0.jar --server.port=8084

java -jar msa-weather-city-eureka-1.0.0.jar --server.port=8085

java -jar msa-weather-city-eureka-1.0.0.jar --server.port=8086

java -jar msa-weather-report-eureka-feign-1.0.0.jar --server.port=8087

java -jar msa-weather-report-eureka-feign-1.0.0.jar --server.port=8088

访问http://localhost:8761页面,可以看到Eureka的管理页面:
在这里插入图片描述
访问http://localhost:8088/report/cityId/101020100页面:
在这里插入图片描述
在页面中切换选中城市:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43415405/article/details/84030904