今日面试题:

1.配置中心的作用? 如何使用?

Spring Cloud Config

在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。在Spring Cloud中,有分布式配置中心组件spring Cloud Config ,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中.
那我们如果想在不重启微服务的情况下更新配置如何来实现呢? 我们使用SpringCloudBus来实现配置的自动更新.
创建Config Server微服务, 用于存放配置文件, 默认使用git存储此项目.
创建Config Client微服务, 用于拉取git上的配置文件, 项目中集成SpringCloudBus对应的消息中间件jar包.
更新配置文件的流程
手动向Mq队列中发送消息,http://127.0.0.1:12000/actuator/bus-refresh(固定地址)
Config Client中的MQ监听到消息, 去git服务器上加载新的配置文件, 并向mq中生产一条配置文件变更的消息.
其他被集中管理的微服务也集成了mq,监听到消息, 向Config Client中重新获取最新的配置文件.

2.nacos如何动态变更配置?

配置热更新:
方式1:在@Value注入的变量所在类上添加注解@RefreshScope
@Slf4j//日志输出
@RestController
@RequestMapping(“/user”)
//@RefreshScope//是修改nacos中的配置后,微服务中无需重启即可让配置生效,也就是配置热更新
public class UserController {

  1. @Autowired<br /> private UserService userService;
  2. @Value("${server.port}")<br /> int port;
  3. /**<br /> * 路径: /user/110<br /> *<br /> * @param id 用户id<br /> * @return 用户<br /> */<br /> @GetMapping("/{id}")<br /> public User queryById(@PathVariable("id") Long id) {<br /> User user = userService.queryById(id);<br /> user.setAddress("" + port);<br /> return user;<br /> }<br />方式2:使用@ConfigurationProperties注解代替@Value注解。<br />在user-service服务中,添加一个类,读取patterrn.dateformat属性,在UserController中使用这个类代替@Value:<br />package cn.itcast.user.web;

import cn.itcast.user.config.PatternProperties;
import cn.itcast.user.pojo.User;
import cn.itcast.user.service.UserService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Slf4j//日志输出
@RestController
@RequestMapping(“/user”)
//@RefreshScope//是修改nacos中的配置后,微服务中无需重启即可让配置生效,也就是配置热更新
public class UserController {

@Autowired<br />    private UserService userService;

@Value("${server.port}")<br />    int port;

/**<br />     * 路径: /user/110<br />     *<br />     * @param id 用户id<br />     * @return 用户<br />     */<br />    @GetMapping("/{id}")<br />    public User queryById(@PathVariable("id") Long id) {<br />        User user = userService.queryById(id);<br />        user.setAddress("" + port);<br />        return user;<br />    }

//    第二种热更新方法<br />    @Autowired<br />    PatternProperties patternProperties;

//    @Value("${pattern.dateformat}")<br />//    private String dateformat;<br />    @GetMapping("now")<br />    public String now() {<br />        //提取当前时间,由配置中心的格式进行格式化<br />        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(patternProperties.getDateformat()));<br />    }

//多变量共享<br />    @GetMapping("prop")<br />    public PatternProperties prop() {<br />        return patternProperties;<br />    }

}

3.nacos如何保证高可用?

搭配集群:

(1):搭建数据库,初始化数据库表结构
(2)下载nacos安装包配置
(3)nacos启动nacos集群
(4)nginx反向代理

4.feign的介绍及作用?

feign是一个声明式的http客户端,其作用就是帮助我们优雅的实现http请求的发送,解决由restTemplate使用时代码可读性差,变成体验不统一,参数复杂,url不同意等问题
使用Feign的步骤:
① 引入依赖
② 添加@EnableFeignClients注解
③ 编写FeignClient接口
④ 使用FeignClient中定义的方法代替RestTemplate

5.如何使用feign进行远程服务调用?使用Feign的步骤:

① 引入依赖

com.itheima
feign-api
1.0

② 添加@EnableFeignClients注解
//开启远程调用的功能
@EnableFeignClients(basePackages = “cn.itcast.feign”,defaultConfiguration = FeignConfig.class)//对整个项目日志均有效
@MapperScan(“cn.itcast.order.mapper”)
@SpringBootApplication
public class OrderApplication {

public static void main(String[] args) {<br />        SpringApplication.run(OrderApplication.class, args);<br />    }<br />③ 编写FeignClient接口<br />//代表他是feign的客户端<br />@FeignClient(value = "userservice",configuration = FeignClient.class)//要调用哪个微服务<br />public interface UserClient {<br />    /**<br />     * 路径: /user/110<br />     *<br />     * @param id 用户id<br />     * @return 用户<br />     */<br />    @GetMapping("/user/{id}")//导入方法去除方法体<br />    public User queryById(@PathVariable("id") Long id);<br />}<br />④ 使用FeignClient中定义的方法代替RestTemplate<br />@RestController<br />@RequestMapping("order")<br />public class OrderController {

@Autowired
private OrderService orderService;

@GetMapping("{orderId}")<br />    public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {<br />        // 根据id查询订单并返回<br />        return orderService.queryOrderById(orderId);<br />    }<br />}

6.feign的基本工作原理?

启动类上加@EnableFeignClients(basePackages=”cn.itcase.order”)
注解之后,会扫描指定的包,找所有标记了@FeignClient注解的接口,使用JDK动态代理创建userClient的代理类对象,讲代理对象直接存放到IOC容器中,要使用时就从ioc容器中拿出用@Autowired注入使用,代理对象方法被调用(InvocationHandler),代理对象方法中,会根据服务名称userservice==获取服务列表==使用Ribbon负载均衡算法得出要调用服务地址

7.是否对feign进行过性能优化?

Feign底层发起http请求,依赖于其它的框架。其底层客户端实现包括:
•URLConnection:默认实现,不支持连接池
•Apache HttpClient :支持连接池
•OKHttp:支持连接池
提高Feign的性能主要手段就是使用连接池代替默认的URLConnection。
步骤:
1.在服务消费者中引入依赖
io.github.openfeign feign-httpclient
2.配置连接池
feign: client: config: default: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置 \ loggerLevel: FULL # 日志级别 \ httpclient: enabled: true # 开启feign对HttpClient的支持 \ max-connections: 200 # 最大的连接数 \ max-connections-per-route: 50 # 每个路径的最大连接数
总结,Feign的优化:

  1. 日志级别尽量用basic
  2. 使用HttpClient或OKHttp代替URLConnection

① 引入feign-httpClient依赖
② 配置文件开启httpClient功能,设置连接池参数

8.gateway网关的介绍及作用?

介绍:Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等响应式编程和事件流技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。
作用:Gateway网关是我们服务的守门神,所有微服务的统一入口。
核心功能特性:请求路由,权限控制,限流
权限控制:网关作为微服务入口,需要校验用户是是否有请求资格,如果没有则进行拦截。
路由和负载均衡:一切请求都必须先经过gateway,但网关不处理业务,而是根据某种规则,把请求转发到某个微服务,这个过程叫做路由。当然路由的目标服务有多个时,还需要做负载均衡。
限流:当请求流量过高时,在网关中按照下流的微服务能够接受的速度来放行请求,避免服务压力过大。

9.如何搭建一个gateway网关?

  1. 1.在父工程下创建一个新Moudle,引入依赖: org.springframework.cloud spring-cloud-starter-gateway com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery 2.创建springBoot启动类3.创建application.yml配置文件:server: port: 10010 # 网关端口spring: application: name: gateway # 服务名称 \ cloud: nacos: server-addr: localhost:80 # nacos地址 \ gateway: routes: # 网关路由配置 \ - id: user-service # 路由id,自定义,只要唯一即可 \ # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址 \ uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称 \ predicates: # 路由断言,也就是判断请求是否符合路由规则的条件 \ - Path=/user/** _# 这个是按照路径匹配,只要以/user/开头就符合要求_4.启动即可

    10.网关中路由的作用?

    根据某种规则(断言工厂),把请求转发到某个微服务,这个过程叫做路由。

    11.gateway中断言的作用?

    配置文件中的断言规则会被Predicate Factory(断言工厂)读取并处理,转变为路由判断的条件.
名称 说明 示例
After 是某个时间点后的请求 - After=2037-01-20T17:42:47.789-07:00[America/Denver]
Before 是某个时间点之前的请求 - Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
Between 是某两个时间点之前的请求 - Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver]
Cookie 请求必须包含某些cookie - Cookie=chocolate, ch.p
Header 请求必须包含某些header - Header=X-Request-Id, \d+
Host 请求必须是访问某个host(域名) - Host=.somehost.org,.anotherhost.org
Method 请求方式必须是指定方式 - Method=GET,POST
Path 请求路径必须符合指定规则 - Path=/red/{segment},/blue/**
Query 请求参数必须包含指定参数 - Query=name, Jack或者- Query=name
RemoteAddr 请求者的ip必须是指定范围 - RemoteAddr=192.168.1.1/24
Weight 权重处理