Spring Cloud Netflix之使用Feign优化前面的Demo

1.声明

当前内容用于本人学习和复习之用,当前内容包括配置Feign和使用,使用Feign优化前面的Demo

前面的Demo:添加了Hystrix的Demo

2.pom依赖和基本的配置

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.3.7.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>SpringCloud-Feign-Demo</groupId>
	<artifactId>SpringCloud-Feign-Demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>SpringCloud-Feign-Demo</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<spring-cloud.version>Brixton.SR5</spring-cloud.version>
		<!-- <springboot.version>1.3.7.RELEASE</springboot.version> -->
	</properties>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
			<!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> 
				<version>${springboot.version}</version> <type>pom</type> <scope>import</scope> 
				</dependency> -->

		</dependencies>
	</dependencyManagement>

	<dependencies>
		<!-- spring cloud 的基本配置 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
			<!-- <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> -->
		</dependency>
		<!-- <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> 
			<version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> 
			</dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> 
			</dependency> -->
		<!-- 为其注入负载均衡,主要使用DiscoveryClient和RestTemplate -->
		<!-- <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> 
			</dependency> -->

		<!-- 注入熔断器 -->
		<!-- <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> 
			</dependency> -->

		<!-- 注入feign -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-feign</artifactId>
		</dependency>
		<!-- spring boot 的基本配置 -->
		<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>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

注释掉hystrix和ribbon,因为当前的feign中已经封装好了

3.使用Feign的基本方式(类似Ribbon的使用)

  1. 为需要的SpringBoot程序的入口类添加@EnableFeignClients
  2. 创建一个访问接口并为其添加@FeignClient指定访问的服务名称
  3. 然后添加和需要访问服务中方法一致的方法签名,返回值也保持一致
  4. 如果需要传递参数则需要使用@RequestParam、@RequestHeader、@RequestBody方式获取参数

4.使用上面的方式实现修改AppDemo中的内容

修改AppDemo上面的注解为

@EnableFeignClients// 开启feign
@EnableHystrixDashboard //开启熔断器仪表盘
/* @EnableCircuitBreaker */// 启动熔断器
@EnableDiscoveryClient
@SpringBootApplication
public class AppDemo {

	/*
	 * @Bean
	 * 
	 * @LoadBalanced // 开启负载均衡 public RestTemplate restTemplate() { return new
	 * RestTemplate(); }
	 */

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

PayService接口,对应pay-service-provider这个服务名称

@FeignClient(value = "pay-service-provider")
public interface PayService {
	@RequestMapping("/pay")
	String pay(@RequestParam("name") String name, @RequestParam("money") Integer money);
}

PermissService接口,对应permiss-service-provider这个服务名称

@FeignClient(value = "permiss-service-provider")
public interface PermissService {
	@RequestMapping("/getPermissByRoleName")
	String getPermissByRoleName(@RequestParam("roleName") String roleName);
}

UserInfoService接口,对应userinfo-service-provider这个服务名称

@FeignClient(value = "userinfo-service-provider")
public interface UserInfoService {
	@RequestMapping("/getUserInfoByName")
	String getUserInfoByName(@RequestParam("name") String name);

	@RequestMapping("/login")
	String login(@RequestParam("name") String name);

	@RequestMapping("/registerUserInfo")
	String registerUserInfo(@RequestParam("name") String name);
}

接下来优化AppController中的内容

@RestController
public class AppController {
	@Autowired
	PermissService permissService;

	@Autowired
	UserInfoService userInfoService;

	// 为该方法采用熔断器
	/*
	 * @HystrixCommand(fallbackMethod = "timeOut", commandProperties = {
	 * 
	 * @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",
	 * value = "8000") })
	 */
	@RequestMapping("/getPermiss")
	public String getPermiss(String roleName) {
		System.out.println("访问App门面中通过角色名称获取用户权限"); 
		return permissService.getPermissByRoleName(roleName);
	}

	/*
	 * public String timeOut(String roleName) { System.out.println("访问超时-->" +
	 * roleName); return "当前访问权限操作,超时了,请过一段时间访问!"; }
	 */

	@RequestMapping("/getUserInfo")
	// 用户信息模块
	public String getUserInfo(String name) {
		System.out.println("访问App门面中通过用户名称获取用户信息");
		return userInfoService.getUserInfoByName(name);
	}

	@RequestMapping("/login")
	public String login(String username) {
		System.out.println("访问App门面中通过用户名称来检查登录");
		return userInfoService.login(username);
	}

	@RequestMapping("/register")
	public String register(String name) {
		System.out.println("访问App门面中注册用户信息");
		return userInfoService.registerUserInfo(name);
	}

	@Autowired
	PayService payService;

	@RequestMapping("/pay")
	public String pay(String name, Integer money) {
		System.out.println("访问App门面中支付服务");
		return payService.pay(name, money);
	}

}

此时发现当前的AppController中的内容非常简单,又回到了原来的SpringBoot中的程序了

5.测试4中的操作

1.启动服务注册中心,随后启动AppDemo,PayServiceApp以及PermissServiceApp(这里就测试这些服务,主要通过AppDemo测试)

2.开始访问
在这里插入图片描述
在这里插入图片描述
这里可以发现测试成功了,但是访问http://localhost:2008/getUserInfo?name=admin出现错误,这是因为我们的UserInfoServiceApp并没有启动(是因为我们需要测试feign熔断器)

6.使用feign实现熔断器的基本操作

1.通过上面创建的访问接口方式创建对应的实现类,如PayService的实现类PayServiceImpl,并为服务实现类添加@Component注解以注册到Spring容器中

2.这里的实现类中的方法前面必须和PayService中的方法签名完全一致,包括注解

3.为当前的@FeignClient中指定当前的fallback=实现类,然后当服务出现熔断或者无法访问的时候,就会默认调用fallback类中对应的方法并返回

7.根据6的熔断器的操作进行修改AppDemo中的内容

1.创建默认的服务熔断实现类

PayService的熔断类

/**
 * @description PayService服务熔断的默认调用实现类
 * @author hy
 * @date 2020-05-02
 */
@Component
public class PayServiceImpl implements PayService {

	@Override
	public String pay(@RequestParam("name") String name, @RequestParam("money") Integer money) {
		return "当前支付服务出现问题,请稍后重试!";
	}

}

PermissService服务熔断的实现类

/**
 * @description PermissService服务熔断的默认调用实现类
 * @author hy
 * @date 2020-05-02
 */
@Component
public class PermissServiceImpl implements PermissService {

	@Override
	public String getPermissByRoleName(@RequestParam("roleName") String roleName) {
		return "无法访问权限服务,请稍后重试!";
	}

}

UserInfoService服务熔断的实现类


/**
 * @description UserInfoService服务熔断的默认调用实现类
 * @author hy
 * @date 2020-05-02
 */
@Component
public class UserInfoServiceImpl implements UserInfoService {
	private static final String MSG_STRING = "当前用户信息服务无法访问,请稍后重试!";

	@Override
	public String getUserInfoByName(@RequestParam("name") String name) {
		return MSG_STRING;
	}

	@Override
	public String login(@RequestParam("name") String name) {
		return MSG_STRING;
	}

	@Override
	public String registerUserInfo(@RequestParam("name") String name) {
		return MSG_STRING;
	}

}

2.修改各个@FeignClient中的内容,为其添加fallback类

@FeignClient(value = "pay-service-provider", fallback = PayServiceImpl.class)
@FeignClient(value = "permiss-service-provider", fallback = PermissServiceImpl.class)
@FeignClient(value = "userinfo-service-provider", fallback = UserInfoServiceImpl.class)

8.测试使用Feign方式实现的熔断器

未启动的时候
在这里插入图片描述
启动UserInfoServiceApp(这里需要等待一下,多次尝试,因为服务拉取需要时间更新)
在这里插入图片描述
测试成功!

9.总结

1.通过使用Feign优化前面的Demo,发现使用了Feign之后controller中的代码少了一半左右,让controller又变成了SpringBoot的controller

2.通过步步操作方式我们发现,Feign优化了RestTemplate的访问方式,优化了Ribbon,而且将熔断器迁移到了外面的实体类中,优化了Hystrix的编写

3.体验完这个Feign发现,使用这个很简单,并且代码也写的很少了

以上纯属个人见解,如有问题请联系本人!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值