1、服务注册
(1)依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
(2)启动类添加注解
@EnableDiscoveryClient
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class SeataOrderApplication {
public static void main(String[] args) {
SpringApplication.run(SeataOrderApplication.class, args);
}
}
(3)配置
spring:
cloud:
nacos:
server-addr: 192.168.1.225:4648
(4)Eureka注册中心
如果注册到 Eureka 中,可以用@EnableEurekaClient,相关依赖、注解和配置如下:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
@EnableEurekaClient
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class SeataOrderApplication {
public static void main(String[] args) {
SpringApplication.run(SeataOrderApplication.class, args);
}
}
eureka:
client:
serviceUrl:
defaultZone: http://192.168.1.225:8761/eureka/
2、使用feign实现 微服务之间调用
(1)依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
(2)启动类添加注解
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class SeataOrderApplication {
public static void main(String[] args) {
SpringApplication.run(SeataOrderApplication.class, args);
}
}
(3)服务消费
@FeignClient(name = "seata-order")
@RequestMapping("/order")
public interface OrderFeignClient {
@RequestMapping("/create")
String create(@RequestParam("userId") Long userId,
@RequestParam("commodityCode") Long commodityCode,
@RequestParam("count") Integer count);
}
@Service
public class BusinessService {
@Autowired
private OrderFeignClient orderFeignClient;
}
(4)服务提供
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping(value = "/create")
public Boolean create(Long userId, Long commodityCode, Integer count) {
orderService.create(userId, commodityCode, count);
return true;
}
}
@FeignClient标签的常用属性如下:
@FeignClient(name = “seata-order”, url = “https://192.168.1.225:18002”)
- name:指定FeignClient的名称,如果项目使用了Ribbon,name属性会作为微服务的名称,用于服务发现
- url:url一般用于调试,可以手动指定@FeignClient调用的地址
- decode404:当发生http404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException
- configuration:Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract
- fallback:定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口
- fallbackFactory:工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码
- path:定义当前FeignClient的统一前缀
3、服务熔断和降级
@FeignClient(name = “seata-order”,fallback = OrderFallback.class)
/**
* 容错处理类,当调用失败时,简单返回空字符串
*/
@Component
public class OrderFallback implements OrderFeignClient {
@Override
public String create(@RequestParam("userId") Long userId,
@RequestParam("commodityCode") Long commodityCode,
@RequestParam("count") Integer count) {
return "";
}
}
Hystrix默认的超时时间是1秒,如果超过这个时间尚未响应,将会进入fallback代码。
该配置是让Hystrix的超时时间改为5秒
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
该配置,用于禁用Hystrix的超时时间
hystrix:
command:
default:
execution:
timeout:
enabled: false
该配置,用于禁用feign的hystrix。
feign:
hystrix:
enabled: false
4、负载均衡
服务提供者添加测试代码如下:
(1)创建RibbonConfig类,定义负载均衡策略
import com.netflix.loadbalancer.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 负载均衡策略
*/
@Configuration
public class RibbonConfig {
/**
* 分配策略
* @return
*/
@Bean
public IRule ribbonRule(){
return new RandomRule(); //分配策略:随机选择一个server
// return new BestAvailableRule(); //分配策略:选择一个最小的并发请求的server,逐个考察Server,如果Server被tripped了,则忽略
// return new RoundRobinRule(); //分配策略:轮询选择,轮询index,选择index对应位置的server
// return new WeightedResponseTimeRule(); //分配策略:根据响应时间分配一个weight(权重),响应时间越长,weight越小,被选中的可能性越低
// return new ZoneAvoidanceRule(); //分配策略:复合判断server所在区域的性能和server的可用性选择server
// return new RetryRule(); //分配策略:对选定的负载均衡策略机上重试机制,在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server
}
@Bean
public IPing ribbonPing() {
return new PingUrl();
}
@Bean
public ServerListSubsetFilter serverListFilter() {
ServerListSubsetFilter filter = new ServerListSubsetFilter();
return filter;
}
}
(2)启动类加注解 @RibbonClient
@RibbonClient(name = "RibbonConfig", configuration = RibbonConfig.class)
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class SeataOrderApplication {
public static void main(String[] args) {
SpringApplication.run(SeataOrderApplication.class, args);
}
}
(3)Controller类加测试方法
@RequestMapping("/ribbon")
public String ribbon() {
return "ribbon----我的端口是:"+serverPort;
}
服务消费者添加测试代码如下:
(1)feign增加远程调用方法
@FeignClient(name = "seata-order")
@RequestMapping("/order")
public interface OrderFeignClient {
@RequestMapping("/ribbon")
String ribbon();
}
(2)启动三个seata-order服务,端口分别是18001、18002、18003
调用结果:
ribbon----我的端口是:18001
ribbon----我的端口是:18002
ribbon----我的端口是:18003
@RibbonClient:用于配置功能区客户端。是否需要@RibbonClient?@RibbonClient什么时候应该使用?
如果您正在使用服务发现,并且对所有默认的功能区设置都没问题,那么甚至不需要使用@RibbonClient注释。
有两种情况需要使用 @RibbonClient
- 您需要为特定的功能区客户端自定义功能区设置
- 您没有使用任何服务发现
5、使用 @LoadBalanced 负载均衡
配置RestTemplate
/**
* 配置bean
* @return
*/
@Bean
@LoadBalanced //开启负载均衡,如果是名称的远程要开启,不然要关闭
RestTemplate restTemplate(){
return new RestTemplate();
}
测试方法
@Autowired
private RestTemplate restTemplate; // RPC调用方法
/**
* 负载均衡测试
* @return
*/
@RequestMapping(value = "/getRibbon")
public String getRibbon(){
// order 使用rpc远程技术调用服务 ,2种调用方法,一种是名称(要开启负载均衡),一个是域名(不用开启负载均衡)
String memberUrl = "http://seata-order/order/ribbon";
// String memberUrl = "http://192.168.1.225:18001/order/ribbon";
String result = restTemplate.getForObject(memberUrl,String.class);
System.out.println("调用Order服务,result:"+result);
return result;
}