SpringCloud服务消费的几种方式

以下示例代码均基于consul注册中心

一、使用LoadBalancerClient

LoadBalancerClient接口的命名中,可以看出这是一个负载均衡客户端的抽象定义,spring提供了一个实现
org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient

1、pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.wzl.springcloud</groupId>
	<artifactId>services-cousmer</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>services-consume</name>
	<description>Demo project for Spring Boot</description>
	
	<properties>
		<!-- 版本管理 -->
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<junit.version>4.12</junit.version>
		<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
	</properties>
	
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.7.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>	
			<artifactId>spring-cloud-starter-consul-discovery</artifactId>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.47</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- spring boot test -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>
	
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>junit</groupId>
				<artifactId>junit</artifactId>
				<version>${junit.version}</version>
				<scope>test</scope>
			</dependency>

			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

2、application.yml

server: 
  #服务端口号
  port: 8080
spring: 
  application: 
    #服务名称
    name: services-consume
  thymeleaf: 
    cache: false
  cloud:
    consul: 
      host: 192.168.12.125 
      port: 8500
      discovery: 
        #是否需要注册到consul中
        register: true
        #服务地址直接为IP地址
        hostname: 192.168.12.1
management:
  endpoints:
    web:
      exposure:
        include: '*'

3、启动类

package com.wzl.springcloud;

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

@SpringBootApplication
@EnableDiscoveryClient
public class ServicesConsumeApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(ServicesConsumeApplication.class, args);
	}

}

4、相关实现类

package com.wzl.springcloud.basic.report.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.wzl.springcloud.basic.report.service.WeatherReportService;
import com.wzl.springcloud.basic.report.vo.City;

@RestController
public class ReportController {
	
	@Autowired
	private WeatherReportService weatherReportService;

	@RequestMapping("/report/getDataByCities")
	public List<City> getDataByCities() {
		return weatherReportService.getDataByCities();
	}

}
package com.wzl.springcloud.basic.report.vo;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

//声明为xml的根元素
@XmlRootElement(name = "d")
// 声明xml的访问类型为FIELD(字段)
@XmlAccessorType(XmlAccessType.FIELD)
public class City {

	// 声明为xml的属性
	@XmlAttribute(name = "d1")
	private String cityId;
	// 声明为xml的属性
	@XmlAttribute(name = "d2")
	private String cityName;
	// 声明为xml的属性
	@XmlAttribute(name = "d3")
	private String cityCode;
	// 声明为xml的属性
	@XmlAttribute(name = "d4")
	private String province;

	public String getCityId() {
		return cityId;
	}

	public void setCityId(String cityId) {
		this.cityId = cityId;
	}

	public String getCityName() {
		return cityName;
	}

	public void setCityName(String cityName) {
		this.cityName = cityName;
	}

	public String getCityCode() {
		return cityCode;
	}

	public void setCityCode(String cityCode) {
		this.cityCode = cityCode;
	}

	public String getProvince() {
		return province;
	}

	public void setProvince(String province) {
		this.province = province;
	}

}
package com.wzl.springcloud.basic.report.service;

import java.util.List;

import com.wzl.springcloud.basic.report.vo.City;

public interface WeatherReportService {

	// 获取所有城市列表
	List<City> getDataByCities();
	
}

package com.wzl.springcloud.basic.report.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.wzl.springcloud.basic.report.service.WeatherReportService;
import com.wzl.springcloud.basic.report.vo.City;

/**
 * LoadBalancer客户端
 */
@Service
public class WeatherReportServiceImpl implements WeatherReportService {

	@Autowired
	private LoadBalancerClient loadBalancer;

	// 城市服务的服务名
	private static final String CITY_SERVICE_NAME = "vis-basic-city";

	@Override
	public List<City> getDataByCities() {
		List<City> cityList = null;
		ServiceInstance serviceInstance = loadBalancer.choose(CITY_SERVICE_NAME);
		String uri = serviceInstance.getUri().toString() + "/cities/getList";
		// 调用服务接口来获取
		ResponseEntity<String> respString = new RestTemplate().getForEntity(uri, String.class);
		// 判断ResponseEntity的状态码是否为200,为200时取出strBody
		if (respString.getStatusCodeValue() == 200) {
			String jsonStr = respString.getBody();
			cityList = JSON.parseArray(jsonStr, City.class);
		}
		return cityList;
	}

}

测试访问

二、使用Ribbon

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。它是一个基于HTTP和TCP的客户端负载均衡器。它可以通过在客户端中配置ribbonServerList来设置服务端列表去轮询访问以达到均衡负载的作用。

1、pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.wzl.springcloud</groupId>
	<artifactId>services-cousmer</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>services-consume</name>
	<description>Demo project for Spring Boot</description>
	
	<properties>
		<!-- 版本管理 -->
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<junit.version>4.12</junit.version>
		<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
	</properties>
	
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.7.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>	
			<artifactId>spring-cloud-starter-consul-discovery</artifactId>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.47</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- spring boot test -->
		<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-netflix-ribbon</artifactId>
        </dependency>
	</dependencies>
	
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>junit</groupId>
				<artifactId>junit</artifactId>
				<version>${junit.version}</version>
				<scope>test</scope>
			</dependency>

			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

2、application.yml

server: 
  #服务端口号
  port: 8080
spring: 
  application: 
    #服务名称
    name: services-consume
  thymeleaf: 
    cache: false
  cloud:
    consul: 
      host: 192.168.12.125 
      port: 8500
      discovery: 
        #是否需要注册到consul中
        register: true
        #服务地址直接为IP地址
        hostname: 192.168.12.1
management:
  endpoints:
    web:
      exposure:
        include: '*'

3、启动类 & RestConfiguration

package com.wzl.springcloud;

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

@SpringBootApplication
@EnableDiscoveryClient
public class ServicesConsumeApplication {

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

}
package com.wzl.springcloud.basic.report.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestConfiguration {

	@Autowired
	private RestTemplateBuilder builder;

	@Bean
	@LoadBalanced
	public RestTemplate restTemplate() {
		return builder.build();
	}

}

@LoadBalanced注解表明这个restRemplate开启负载均衡的功能,用LoadBalancerClient配置,并且会替换URL中的服务名称为具体的IP地址

4、相关实现类

package com.wzl.springcloud.basic.report.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.wzl.springcloud.basic.report.service.WeatherReportService;
import com.wzl.springcloud.basic.report.vo.City;

@RestController
public class ReportController {
	
	@Autowired
	private WeatherReportService weatherReportService;

	@RequestMapping("/report/getDataByCities")
	public List<City> getDataByCities() {
		return weatherReportService.getDataByCities();
	}

}
package com.wzl.springcloud.basic.report.vo;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

//声明为xml的根元素
@XmlRootElement(name = "d")
// 声明xml的访问类型为FIELD(字段)
@XmlAccessorType(XmlAccessType.FIELD)
public class City {

	// 声明为xml的属性
	@XmlAttribute(name = "d1")
	private String cityId;
	// 声明为xml的属性
	@XmlAttribute(name = "d2")
	private String cityName;
	// 声明为xml的属性
	@XmlAttribute(name = "d3")
	private String cityCode;
	// 声明为xml的属性
	@XmlAttribute(name = "d4")
	private String province;

	public String getCityId() {
		return cityId;
	}

	public void setCityId(String cityId) {
		this.cityId = cityId;
	}

	public String getCityName() {
		return cityName;
	}

	public void setCityName(String cityName) {
		this.cityName = cityName;
	}

	public String getCityCode() {
		return cityCode;
	}

	public void setCityCode(String cityCode) {
		this.cityCode = cityCode;
	}

	public String getProvince() {
		return province;
	}

	public void setProvince(String province) {
		this.province = province;
	}

}
package com.wzl.springcloud.basic.report.service;

import java.util.List;

import com.wzl.springcloud.basic.report.vo.City;

public interface WeatherReportService {

	// 获取所有城市列表
	List<City> getDataByCities();

}
package com.wzl.springcloud.basic.report.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.wzl.springcloud.basic.report.service.WeatherReportService;
import com.wzl.springcloud.basic.report.vo.City;

/**
 * Ribbon客户端
 */
@Service
public class WeatherReportServiceImpl implements WeatherReportService {

	@Autowired
	// 对rest客户端的封装
	private RestTemplate restTemplate;

	// 城市服务的服务名
	private static final String CITY_SERVICE_NAME = "vis-basic-city";

	@Override
	public List<City> getDataByCities() {
		List<City> cityList = null;
		String uri = "http://" + CITY_SERVICE_NAME + "/cities/getList";
		// 调用服务接口来获取
		ResponseEntity<String> respString = restTemplate.getForEntity(uri, String.class);
		// 判断ResponseEntity的状态码是否为200,为200时取出strBody
		if (respString.getStatusCodeValue() == 200) {
			String jsonStr = respString.getBody();
			cityList = JSON.parseArray(jsonStr, City.class);
		}
		return cityList;
	}

}

测试访问

三、使用Feign

Feign是一个声明性的web服务客户端,它使编写web服务客户机变得更容易。
总结特点:
1、Feign采用的是接口加注解,就像调用本地方法一样调用远程服务
2、Feign整合了Ribbon,当你使用@FeignClient,Ribbon自动被应用,所以也会负载均衡
3、Feign是一种声明式、模板化的HTTP客户端。

1、pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.wzl.springcloud</groupId>
	<artifactId>services-cousmer</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>services-consume</name>
	<description>Demo project for Spring Boot</description>
	
	<properties>
		<!-- 版本管理 -->
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<junit.version>4.12</junit.version>
		<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
	</properties>
	
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.7.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>	
			<artifactId>spring-cloud-starter-consul-discovery</artifactId>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.47</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- spring boot test -->
		<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-openfeign</artifactId>
		</dependency>
	</dependencies>
	
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>junit</groupId>
				<artifactId>junit</artifactId>
				<version>${junit.version}</version>
				<scope>test</scope>
			</dependency>

			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

2、application.yml

server: 
  #服务端口号
  port: 8080
spring: 
  application: 
    #服务名称
    name: services-consume
  thymeleaf: 
    cache: false
  cloud:
    consul: 
      host: 192.168.12.125 
      port: 8500
      discovery: 
        #是否需要注册到consul中
        register: true
        #服务地址直接为IP地址
        hostname: 192.168.12.1
management:
  endpoints:
    web:
      exposure:
        include: '*'

3、启动类

package com.wzl.springcloud.basic.report;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
public class ReportServerApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(ReportServerApplication.class, args);
	}

}

4、相关实现类

package com.wzl.springcloud.basic.report.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.wzl.springcloud.basic.report.service.WeatherReportService;
import com.wzl.springcloud.basic.report.vo.City;

@RestController
public class ReportController {
	
	@Autowired
	private WeatherReportService weatherReportService;

	@RequestMapping("/report/getDataByCities")
	public List<City> getDataByCities() {
		return weatherReportService.getDataByCities();
	}

}
package com.wzl.springcloud.basic.report.vo;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

//声明为xml的根元素
@XmlRootElement(name = "d")
// 声明xml的访问类型为FIELD(字段)
@XmlAccessorType(XmlAccessType.FIELD)
public class City {

	// 声明为xml的属性
	@XmlAttribute(name = "d1")
	private String cityId;
	// 声明为xml的属性
	@XmlAttribute(name = "d2")
	private String cityName;
	// 声明为xml的属性
	@XmlAttribute(name = "d3")
	private String cityCode;
	// 声明为xml的属性
	@XmlAttribute(name = "d4")
	private String province;

	public String getCityId() {
		return cityId;
	}

	public void setCityId(String cityId) {
		this.cityId = cityId;
	}

	public String getCityName() {
		return cityName;
	}

	public void setCityName(String cityName) {
		this.cityName = cityName;
	}

	public String getCityCode() {
		return cityCode;
	}

	public void setCityCode(String cityCode) {
		this.cityCode = cityCode;
	}

	public String getProvince() {
		return province;
	}

	public void setProvince(String province) {
		this.province = province;
	}

}
package com.wzl.springcloud.basic.report.feign;

import java.util.List;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

import com.wzl.springcloud.basic.report.vo.City;

@FeignClient(name = "vis-basic-city")
@RequestMapping("/cities")
public interface CityApiFeign {

	@RequestMapping("/getList")
	public List<City> listCity();

}
package com.wzl.springcloud.basic.report.service;

import java.util.List;

import com.wzl.springcloud.basic.report.vo.City;

public interface WeatherReportService {

	// 获取所有城市列表
	List<City> getDataByCities();

}
package com.wzl.springcloud.basic.report.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.wzl.springcloud.basic.report.feign.CityApiFeign;
import com.wzl.springcloud.basic.report.service.WeatherReportService;
import com.wzl.springcloud.basic.report.vo.City;


/**
 * Feign客户端
 */
@Service
public class WeatherReportServiceImpl implements WeatherReportService {
	
	@Autowired
	private CityApiFeign cityApiFeign;
	
	@Override
	public List<City> getDataByCities() {
		return cityApiFeign.listCity();
	}

}

测试访问

四、通过网关调用服务

在微服务框架中,每个对外服务都是独立部署的,对外的API或者服务地址都不是不尽相同的。对于内部而言,很简单,通过注册中心自动感知即可。但我们大部分情况下,服务都是提供给外部系统进行调用的,不可能同享一个注册中心。同时一般上内部的微服务都是在内网的,和外界是不连通的。而且,就算我们每个微服务对外开放,对于调用者而言,调用不同的服务的地址或者参数也是不尽相同的,这样就会造成消费者客户端的复杂性,同时想想,可能微服务可能是不同的技术栈实现的,有的是http、rpc或者websocket等等,也会进一步加大客户端的调用难度。所以,一般上都有会有个api网关,根据请求的url不同,路由到不同的服务上去,同时入口统一了,还能进行统一的身份鉴权、日志记录、分流等操作。接下来就是基于zuul的服务调用。

需要提前搭建好网关服务,以下示例代码基于zuul网关

1、网关zuul的application.yml配置

server: 
  #服务端口号 
  port: 7070
spring: 
  application: 
    #服务的名称
    name: vis-basic-zuul
  #指定注册中心地址
  cloud: 
    consul: 
      host: 192.168.12.125
      port: 8500
      discovery: 
        #是否需要注册到consul中
        register: true
        #服务地址直接为IP地址
        hostname: 192.168.12.1
        service-name: ${spring.application.name}      
        healthCheckPath: /actuator/health
        healthCheckInterval: 15s
        
zuul: 
  #表示不暴露配置之外的服务
  ignored-services: '*'
  routes: 
    #天气服务
    vis-basic-weather: 
      path: /api-weather/**
      service-id: vis-basic-weather
      
    #城市服务
    vis-basic-city: 
      path: /api-city/**
      service-id: vis-basic-city
      

2、pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.wzl.springcloud</groupId>
	<artifactId>services-cousmer</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>services-consume</name>
	<description>Demo project for Spring Boot</description>
	
	<properties>
		<!-- 版本管理 -->
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<junit.version>4.12</junit.version>
		<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
	</properties>
	
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.7.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>	
			<artifactId>spring-cloud-starter-consul-discovery</artifactId>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.47</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- spring boot test -->
		<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-openfeign</artifactId>
		</dependency>
	</dependencies>
	
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>junit</groupId>
				<artifactId>junit</artifactId>
				<version>${junit.version}</version>
				<scope>test</scope>
			</dependency>

			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

3、application.yml

server: 
  #服务端口号
  port: 8080
spring: 
  application: 
    #服务名称
    name: services-consume
  thymeleaf: 
    cache: false
  cloud:
    consul: 
      host: 192.168.12.125 
      port: 8500
      discovery: 
        #是否需要注册到consul中
        register: true
        #服务地址直接为IP地址
        hostname: 192.168.12.1
management:
  endpoints:
    web:
      exposure:
        include: '*'
  

4、启动类

package com.wzl.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
public class ServicesConsumeApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(ServicesConsumeApplication.class, args);
	}

}

5、相关实现类

package com.wzl.springcloud.basic.report.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.wzl.springcloud.basic.report.service.WeatherReportService;
import com.wzl.springcloud.basic.report.vo.City;

@RestController
public class ReportController {
	
	@Autowired
	private WeatherReportService weatherReportService;

	@RequestMapping("/report/getDataByCities")
	public List<City> getDataByCities() {
		return weatherReportService.getDataByCities();
	}

}
package com.wzl.springcloud.basic.report.vo;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

//声明为xml的根元素
@XmlRootElement(name = "d")
// 声明xml的访问类型为FIELD(字段)
@XmlAccessorType(XmlAccessType.FIELD)
public class City {

	// 声明为xml的属性
	@XmlAttribute(name = "d1")
	private String cityId;
	// 声明为xml的属性
	@XmlAttribute(name = "d2")
	private String cityName;
	// 声明为xml的属性
	@XmlAttribute(name = "d3")
	private String cityCode;
	// 声明为xml的属性
	@XmlAttribute(name = "d4")
	private String province;

	public String getCityId() {
		return cityId;
	}

	public void setCityId(String cityId) {
		this.cityId = cityId;
	}

	public String getCityName() {
		return cityName;
	}

	public void setCityName(String cityName) {
		this.cityName = cityName;
	}

	public String getCityCode() {
		return cityCode;
	}

	public void setCityCode(String cityCode) {
		this.cityCode = cityCode;
	}

	public String getProvince() {
		return province;
	}

	public void setProvince(String province) {
		this.province = province;
	}

}
package com.wzl.springcloud.basic.report.feign;

import java.util.List;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

import com.wzl.springcloud.basic.report.vo.City;

@FeignClient(name = "vis-basic-zuul")
@RequestMapping("/api-city/cities")
public interface CityApiFeignGateway {

	@RequestMapping("/getList")
	public List<City> listCity();

}
package com.wzl.springcloud.basic.report.service;

import java.util.List;

import com.wzl.springcloud.basic.report.vo.City;

public interface WeatherReportService {

	// 获取所有城市列表
	List<City> getDataByCities();

}
package com.wzl.springcloud.basic.report.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.wzl.springcloud.basic.report.feign.CityApiFeignGateway;
import com.wzl.springcloud.basic.report.service.WeatherReportService;
import com.wzl.springcloud.basic.report.vo.City;


/**
 * FeignGateway客户端
 */
@Service
public class WeatherReportServiceImpl implements WeatherReportService {
	
	@Autowired
	private CityApiFeignGateway cityApiFeignGateway;
	
	@Override
	public List<City> getDataByCities() {
		return cityApiFeignGateway.listCity();
	}

}

测试访问

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章