1. Feign substitui RestTemplate
Exemplo RestTemplate
String url = "http://userservice/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);
Defeitos do RestTemplate:
- A legibilidade do código é ruim e a experiência de codificação não é uniforme.
- URLs com parâmetros complexos são difíceis de manter
(1) O conceito de Fegin
Fegin é um cliente http declarativo. O site oficial: https://github.com/OpenFeign/feign é
usado para ajudar a simplificar o envio de solicitações http.
(2) Uso básico do Fegin
1. Introduzir dependências
<dependency>
<groupId>org.springframework.cloud</gourpId>
<artifactId>spring.cloud.starter.openfeign</artifactId>
</dependency>
2. Adicione anotações à classe de inicialização para iniciar o Fegin
@EnableFeignClients //启动Fegin客户端
@MapperScan("xxx.xxx.xxx.mapper")
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class,args);
}
}
3. Defina o cliente Fegin
@FeignClient("userservice")
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
Baseia-se principalmente nas anotações do SpringMVC para declarar informações de chamadas remotas, como:
- Nome do serviço: userservice
- Método de solicitação: GET
- Caminho da solicitação: /user/{id}
- Parâmetro de solicitação: ID longo
- Valor de retorno: usuário
3. O serviço usa o cliente Feign
@Service
public class OrderService {
@Autowired
private OrderMapper mapper;
@Autowired
private UserClient userClient;
public Order queryOrderById(Long orderId) {
Order order = orderMapper.findById(orderId);
User user = userClient.getById(order.getUserId());
order.setUser(user);
return order;
}
}
2. Configuração personalizada
Uma tabela de configuração modificável
tipo | efeito | ilustrar |
---|---|---|
fegin.Logger.Level | Modificar nível de log (comum) |
Contém quatro níveis: NENHUM, BÁSICO, CABEÇALHOS, COMPLETO
|
fegin.codec.Decoder | analisador de resultado de resposta |
Analise os resultados de chamadas remotas http, como análise de JSON
|
fegin.codec.Encoder | Solicitar formato de codificação de parâmetro |
Codifique os parâmetros de solicitação para facilitar o envio de solicitações http
|
fegin.Contract | Formatos de anotação suportados |
O padrão são as anotações do SpringMVC
|
feliz.Retryer | Mecanismo de repetição de falha |
O mecanismo de repetição para falha de solicitação, o padrão é não, mas a repetição da faixa de opções será usada
|
(1) Realização da modificação da configuração
Método 1: método de arquivo de configuração
fegin:
client:
config:
default: #设置全局配置,若是直接写服务名称,则是针对某一个微服务的配置
loggerLevel: FULL #全日志级别
Método 2: Personalize a configuração do Feign
Classe de configuração FeignClientConfiguration
//配置注解选择一种即可
//全局配置:在启动类上加上该注解
//@EnableFeginClients(defaultConfiguration = FeignClientConfiguration.class)
//局部配置:具体Client类上加该注解
//@FeginClient(value = "userservice", configuration = FeignClientConfiguration.class)
public class FeignClientConfiguration {
@Bean
public Logger.Level.feignLogLevel(){
return Logger.Level.BASIC;
}
}
3. Fingir otimização
(1) Implementação do cliente subjacente de Feign (três modos)
- URLConnection: implementado por padrão, não suporta pool de conexões (o JDK vem com ele)
- Apache HttpClient: suporta pool de conexões
- OKHttp: pool de conexões de suporte
(2) Otimizando o desempenho da Fegin
- 1. Use pool de conexão em vez de URLConnection
- 2. Nível de log, preferencialmente configurado como BASIC ou NONE
(3) Configure o pool de conexões em vez de URLConnection
1. Introduza a dependência HttpClient
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
2. Configure o pool de conexões
feign:
client:
config:
default: #全局配置
loggerLevel: BASIC #日志级别,打印最基本的请求和响应信息
httpclient:
enabled: true #开启feign对httpclient的支持
max-connections: 200 #最大连接数
max-connections-per-route: 50 #每个路径的最大连接数
Quarto, a experiência de implementação do FeignClient resumida na prática
(1) Método 1 (herança): Defina uma interface pai unificada para o FeignClient do consumidor e o controlador do provedor como padrão.
1. Perceba:
interface pai
public interface UserAPI{
@GetMapping("/user/{
id})
User findById(@PathVariable("id") Long id);
}
UserClient herda a interface pai
@FeignClient(value = "userservice")
public interface UserClient extends UserAPI{
}
UserController implementa a interface pai
@RestController
public class UserController implements UserAPI {
public User findById(@PathVariable("id") Long id) {
//...实现业务
}
}
2. Defeitos deste método
- Serviços fortemente acoplados
- O mapeamento da lista de parâmetros da interface pai não será herdado
(2) Método 2 (extração): Extraia FeignClient como um módulo independente e coloque o POJO relacionado à interface e a configuração Feign padrão neste módulo para uso de todos os consumidores.
1. Perceba
(1) Criação do módulo
Crie um módulo, chamado feign-api, e introduza a dependência inicial do feign
(2) Extração da classe de função do módulo
Coloque a classe que precisa ser extraída no módulo feign-api.
(3) Use fingir-api
O serviço ao consumidor apresenta a dependência de feign-api
(4) Importação de serviço ao consumidor feign-api
2. Possíveis problemas
UserClient não é criado como um objeto Bean pelo Spring
-
Razão: FeginClient está fora do escopo da verificação do pacote de serviços ao consumidor, resultando na introdução de nenhuma instância.
-
solução:
Método 1: Especifique FeignClient para ficar no pacote
@EnableFeignClients(basePackages = "xxx.xxx.xxx.clients")
Método 2: Especifique o bytecode FeignClient
@EnableFeignClients(clients= {
UserClient.class})