面试题目
本文最后更新于:1 个月前
使用url实现访问一个非80端口的服务
Nginx实现代理转发
面试官问了一个问题,如何,当时靠着感觉说了nginx的反向代理的实现,后面查询了实现方法,nginx确实可以实现这个功能。
实现也很简单,配置一个ngnix的转发功能即可
server {
listen 80;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://localhost:8099/;
}
}
Nginx实现反向代理
主要配置为upstream
字段,其中配置了已经部署的服务器地址,默认的负载均衡规则是轮询,也可以配置为根据权重分配访问,还有IP_Hash规则。
upstream myservice {
server 127.0.0.1:8081;
server 127.0.0.1:8083;
# server 127.0.0.1:8847;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://myservice;
}
限流算法–保证api每秒钟只能被访问10次
可以使用令牌桶算法实现
- 令牌的生成:系统以固定的速率向令牌桶中添加令牌
- 令牌的消耗:每个传入的请求或操作需要从令牌桶中取出一个令牌才能继续执行。如果桶中没有令牌,则请求必须等待直到桶中有可用的令牌
- 令牌的限制:令牌桶中的数量不能超过10个,保证任何时间传输的峰值速率不会超出预设的上限
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class RateLimiter {
private Semaphore semaphore;
private int maxPermits;
private TimeUnit timePeriod;
private long rateLimitRefreshPeriod;
private long lastRefreshTime;
public RateLimiter(int maxPermits, TimeUnit timePeriod) {
// 信号量
this.semaphore = new Semaphore(maxPermits);
// 单位时间内的最大访问次数
this.maxPermits = maxPermits;
// 时间单位
this.timePeriod = timePeriod;
// 刷新的周期1s
this.rateLimitRefreshPeriod = timePeriod.toMillis(1);
this.lastRefreshTime = System.currentTimeMillis();
}
public boolean tryAcquire() {
refreshPermits();
return semaphore.tryAcquire();
}
private synchronized void refreshPermits() {
long now = System.currentTimeMillis();
// 如果当前时间与最后更新时间间隔超过了刷新周期,则向令牌桶中添加令牌
if (now - lastRefreshTime > rateLimitRefreshPeriod) {
// 向令牌桶中添加新的令牌
semaphore.release(maxPermits - semaphore.availablePermits());
// 更新最后的刷新时间
lastRefreshTime = now;
}
}
public static void main(String[] args) throws InterruptedException {
RateLimiter rateLimiter = new RateLimiter(10, TimeUnit.SECONDS);
// 模拟请求
for (int i = 0; i < 100; i++) {
if (rateLimiter.tryAcquire()) {
System.out.println("Request " + i + " is allowed at " + System.currentTimeMillis());
} else {
System.out.println("Request " + i + " is denied at " + System.currentTimeMillis());
}
Thread.sleep(50); // 模拟请求间隔时间
}
}
}
第0请求成功, 剩余令牌数量9 当前时间:1713681644849
第1请求成功, 剩余令牌数量8 当前时间:1713681644904
第2请求成功, 剩余令牌数量7 当前时间:1713681644967
第3请求成功, 剩余令牌数量6 当前时间:1713681645030
第4请求成功, 剩余令牌数量5 当前时间:1713681645092
第5请求成功, 剩余令牌数量4 当前时间:1713681645154
第6请求成功, 剩余令牌数量3 当前时间:1713681645217
第7请求成功, 剩余令牌数量2 当前时间:1713681645279
第8请求成功, 剩余令牌数量1 当前时间:1713681645341
第9请求成功, 剩余令牌数量0 当前时间:1713681645404
第10请求失败, 剩余令牌数量0 当前时间:1713681645465
第11请求失败, 剩余令牌数量0 当前时间:1713681645527
第12请求失败, 剩余令牌数量0 当前时间:1713681645591
第13请求失败, 剩余令牌数量0 当前时间:1713681645653
第14请求失败, 剩余令牌数量0 当前时间:1713681645714
第15请求失败, 剩余令牌数量0 当前时间:1713681645776
第16请求失败, 剩余令牌数量0 当前时间:1713681645837
第17请求成功, 剩余令牌数量9 当前时间:1713681645899
第18请求成功, 剩余令牌数量8 当前时间:1713681645962
第19请求成功, 剩余令牌数量7 当前时间:1713681646024
第20请求成功, 剩余令牌数量6 当前时间:1713681646086
第21请求成功, 剩余令牌数量5 当前时间:1713681646149
第22请求成功, 剩余令牌数量4 当前时间:1713681646211
第23请求成功, 剩余令牌数量3 当前时间:1713681646274
第24请求成功, 剩余令牌数量2 当前时间:1713681646336
第25请求成功, 剩余令牌数量1 当前时间:1713681646398
第26请求成功, 剩余令牌数量0 当前时间:1713681646461
从打印的日志可以看到,实现了每秒钟只能访问10次的限制
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!