Eureka 主机名还是ip
我们把每个java进程部署在一个Docker容器中,子服务通过注册中心找到配置中心,然后访问配置中心拿到对应的配置信息。
之前子服务在物理机部署是没有问题的,但是在容器中出错,日志信息是:
2017-12-04 19:54:44.213 INFO [xxx,,,] 1 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://iZ2zehfslfx46hf71lp8zzZ:9910/
可以看到访问地址是别名(iZ2zehfslfx46hf71lp8zzZ),而这个别名可以在配置中心所在容器的hosts文件中查到。
ip_address iZ2zehfslfx46hf71lp8zzZ
子服务所在容器hosts里面并没有这个对应关系,所以访问不到配置中心。
解决方案是让子服务优先使用IP而不是主机名来访问。
eureka.instance.prefer-ip-address=true
在添加配置之后问题解决。
Mysql分页查询优化
内容节选自阿里<逆流而上:阿里巴巴技术成长之路>
table info
CREATE TABLE `t_test_buyer` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(10) DEFAULT NULL,
`sellerid` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `selleridIndex` (`sellerid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
这张表有200万条记录,sellerid从1-10,每个id大约在20万左右数据。
select * from t_test_buyer where sellerid=1 limit 200000,5000
查询耗时280ms左右。
如何对这条sql进行优化呢?
Mysql翻页是LIMIT M, N,即查询出M+N条记录,然后取后N条记录,所以M越大性能越差。
查看下sql执行计划
explain select * from t_test_buyer where sellerid=1 limit 200000,5000
1 SIMPLE t_test_buyer ref selleridIndex selleridIndex 4 const 528736 NULL
如果把 * 改为 id
explain select SQL_NO_CACHE id from t_test_buyer where sellerid=1 limit 200000,5000
1 SIMPLE t_test_buyer ref selleridIndex selleridIndex 4 const 528736 Using index
可以发现当把 * 改为 id时,直接通过索引获取结果,不再需要拿到所有字段,可以加快查询速度。
那么优化后
select SQL_NO_CACHE t1.* from t_test_buyer t1, (select id from t_test_buyer where sellerid=1 limit 200000,5000) t2 where t1.id=t2.id
1 PRIMARY ALL NULL NULL NULL NULL 205000 NULL
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 t2.id 1 NULL
2 DERIVED t_test_buyer ref selleridIndex selleridIndex 4 const 528736 Using index
优化后的sql查询耗时在52ms左右,性能有了明显的提升。
其实在数据量不大的情况下,2种方式看起来差别不大,但是当数据量上去之后,好的方法和差的方法变有了非常显著的区别;所以平时开发时要注意细节,着眼于更好的性能,提升自己的开发水准。
Nginx vs Zuul性能比较
参考: 国外测评 | 国内翻译文章
决定自己测试下看看2者性能之间差异。
Web
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class TestMvcApplication {
public static void main(String[] args) {
SpringApplication.run(TestMvcApplication.class, args);
}
@RestController
class HelloController {
@RequestMapping("/")
public String hello() {
return "hello";
}
}
}
仅仅提供一个最简单的接口供外部访问。
Zuul
POM文件中需要引入Cloud依赖。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableZuulProxy
public class TestZuulApplication {
public static void main(String[] args) {
SpringApplication.run(TestZuulApplication.class, args);
}
}
application.yml 配置转发
zuul:
routes:
users:
path: /**
url: http://ip:8081
server:
port: 8082
Nginx
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 8083 default_server;
listen [::]:8083 default_server ipv6only=on;
# Make site accessible from http://localhost/
server_name localhost;
# allow file upload
client_max_body_size 10M;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://ip:8081;
}
}
}
仅仅配置简单的转发功能。
测试
使用ab来对接口进行简单测试。
ab -n 10000 -c 200 http://ip:port/
Nginx
Server Software: nginx/1.13.7
Server Hostname: 59.110.14.254
Server Port: 8083
Document Path: /
Document Length: 5 bytes
Concurrency Level: 200
Time taken for tests: 51.452 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 1593657 bytes
HTML transferred: 50115 bytes
Requests per second: 194.36 [#/sec] (mean)
Time per request: 1029.043 [ms] (mean)
Time per request: 5.145 [ms] (mean, across all concurrent requests)
Transfer rate: 30.25 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 1 134 419.9 1 5524
Processing: 2 285 1993.2 2 51389
Waiting: 2 264 1994.7 2 51389
Total: 3 420 2041.7 5 51390
Percentage of the requests served within a certain time (ms)
50% 5
66% 28
75% 207
80% 209
90% 1006
95% 1424
98% 3043
99% 6280
100% 51390 (longest request)
Zuul
Server Software:
Server Hostname: 59.110.14.254
Server Port: 8082
Document Path: /
Document Length: 5 bytes
Concurrency Level: 200
Time taken for tests: 51.454 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 1590636 bytes
HTML transferred: 50020 bytes
Requests per second: 194.35 [#/sec] (mean)
Time per request: 1029.074 [ms] (mean)
Time per request: 5.145 [ms] (mean, across all concurrent requests)
Transfer rate: 30.19 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 1 105 346.3 1 5267
Processing: 2 406 3231.0 2 51403
Waiting: 2 389 3232.5 2 51403
Total: 3 512 3247.6 4 51405
Percentage of the requests served within a certain time (ms)
50% 4
66% 7
75% 206
80% 208
90% 1003
95% 1209
98% 3042
99% 7288
100% 51405 (longest request)
对比发现,两者性能已经很接近了;比较如下,Nginx优点是占用内存小,Zuul优点是功能强大,可以进行鉴权等操作,同时基于Spring Cloud生态圈,所以完全可以使用Zuul代替Nginx。