启动stand_alone模式,并进行配置
修改config.yaml
apisix镜像怎么做之前博客已经说了,现在启动镜像,在/usr/local/apisix/conf/config.yaml中删除原来配置的所有东西,加上:
apisix:
enable_admin: false # 关闭admin api
config_center: yaml #以yaml文件为配置中心
配置中心apisix.yaml
配置usr/local/apisix/conf/apisix.yaml(注意,yaml配置中心下,不能把上游配置在路由里面,插件会失效)
;并且开启权限插件必须有consumer,并且不像限流熔断这些插件配置在route上就算是开启了,权限插件除了在consumer配置,还要在route上配置。
routes:
-
uri: /myinfo
upstream_id: 1
plugins:
http-logger:
batch_max_size: 1 # 日志缓存数,日志会缓存起来,数量达到batch_max_size则发送post请求
uri: http://172.28.118.121:8080/test # 宿主机的/路径下有个test_apisix.jar,用来接受日志post请求
jwt-auth: # 开启权限插件,后面不写,具体都在consumer配好了
limit-count:
count: 1000 # 限制连接数量
time_window: 1 # 时间窗,单位秒
api-breaker:
break_response_code: 502 熔断返回值
unhealthy: [500],
failures: 3
response-rewrite:
# 重写响应体
body: "{\"code\":\"ok\",\"message\":\"new json body\"}"
# 重写响应头
headers:
X-Server-id: 3
X-Server-status: "on"
X-Server-balancer_addr: "88.88.88.88"
proxy-rewrite:
# 转发路径
uri: "/description"
# 转发协议
scheme: "http"
# 转发请求头
headers:
X-Api-Version: "v1"
X-Api-Engine: "apisix"
upstreams:
- id: 1
nodes:
"159.75.26.246:80": 1
type: roundrobin
consumers:
- username: test_user
plugins:
jwt-auth:
key: test-key 和当前consumer # 对应,且全局唯一,不可和其他consumer重复
secret: my-secret-key # 生成token的密钥
plugin_metadata: # 更改日志插件元数据,只输出两个地址
- id: http-logger
log_format:
host: "$host",
remote_addr: "$remote_addr"
#END
启动apisix
启动apisix
apisix start
测试
测试日志
日志插件配置的url是发送post请求的url,请求体是json字符串
curl http://127.0.0.1:9080/myinfo
测试结果如下
测试限流
如图
测试熔断
上述上游的url是“159.75.26.246:80”,转发到的真实地址是“159.75.26.246:80/myinfo”。直接关闭我的网站,多次请求返回502,则表示熔断成功。
在网站关闭前,可以成功访问,关闭后是不会显示404的,apisix会认为该服务可能暂时下线进而熔断
测试jwt
(1)HS256算法生成token
a)内部生成token
参数key是consumer的jwt插件设置的key,这个key和consumer关联且唯一
curl http://172.28.118.121:9081/apisix/plugin/jwt/sign?key=test-key
b)外部生成token
以springboot项目为例
pom文件依赖如下
<dependencies>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
main函数如下
public class Main {
public static void main(String[] args) throws UnsupportedEncodingException {
String token = JWT.create()
.withClaim("key", "test-key") //jwt插件的key是作为jwt的载荷
.sign(Algorithm.HMAC256("my-secret-key")); //jwt默认HS256算法
System.out.println(token);
}
}
(2) RSA算法生成token
a) 插件配置
# 在apisix.yaml中设置
routes:
-
uri: /myinfo
upstream_id: 1
plugins:
limit-count:
count: 1000
time_window: 1
jwt-auth:
consumers:
- username: jwt
plugins:
jwt-auth:
key: test-key
public_key: |
-----BEGIN PUBLIC KEY-----
xxxxxxxxxx
-----END PUBLIC KEY-----
private_key: |
-----BEGIN PRIVATE KEY-----
xxxxxxxxxxx
-----END PRIVATE KEY-----
algorithm: RS256
b) 内部生成token
参数key是consumer的jwt插件设置的key,这个key和consumer关联且唯一
curl http://172.28.118.121:9081/apisix/plugin/jwt/sign?key=test-key
c)外部生成token
以springboot项目为例
pom文件依赖如下
<dependencies>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
main函数如下
公钥和私钥都是字符串形式,且不能带-----BEGIN xxx KEY-----和-----END xxx KEY-----
公钥私钥可以网上在线生成,也可以借助openssl生成
public class Main {
public static String publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxRymaMWrPEvMfzaF+yv2"
+ "IftZiPZvh6q1HwlS41JaNP9uTZGxbyHBajftqsWJ+STnhHpGWvsyfnDmWRoUSogY" + "lW40pfAwZm6XCo5nKnX59YRzmqWqjPXQfb7xa8341jz2tjVYtMD1LoKry5oxhSOk"
+ "wGrZq9O9MO4NwcEMCQ86Cqw/hzGiKFEyH+j6nJWISJsWtkQxh7U5dIIQaISk6Eec" + "C0piNb7TeaDkYu0iqPom4MtVrVwGUOa2obXBPV9nonu6CNZzhfqoRBeb4zucwCfJ"
+ "Ro81CnkzZ+jfCThxn95ssE8daNND8sgElYc7mBCa72L75YsG6fZyMkGIj5mQ1Z94" + "4wIDAQAB";
public static String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDFHKZoxas8S8x/"
+ "NoX7K/Yh+1mI9m+HqrUfCVLjUlo0/25NkbFvIcFqN+2qxYn5JOeEekZa+zJ+cOZZ" + "GhRKiBiVbjSl8DBmbpcKjmcqdfn1hHOapaqM9dB9vvFrzfjWPPa2NVi0wPUugqvL"
+ "mjGFI6TAatmr070w7g3BwQwJDzoKrD+HMaIoUTIf6PqclYhImxa2RDGHtTl0ghBo" + "hKToR5wLSmI1vtN5oORi7SKo+ibgy1WtXAZQ5rahtcE9X2eie7oI1nOF+qhEF5vj"
+ "O5zAJ8lGjzUKeTNn6N8JOHGf3mywTx1o00PyyASVhzuYEJrvYvvliwbp9nIyQYiP" + "mZDVn3jjAgMBAAECggEBAJLKgUspWhpvQH3EdwbUeFpaOxV6oRhhkrzoTqgn3jH1"
+ "v4lY5NCkTMvzlrVEozm9uAS6osaCp9nt7j2Q5GeU7unpxp+FPiYqWaVs43uFnH6x" + "Av66PUb4kSn0Fwp3u8agZALRu5vwzyax/YqE7DgAkWMSr8P8zbowrmIKiBH/GvRy"
+ "f8gCtkHQNRn6G/5mI63YvpqId0fmLzgr6g/FCFwRYkmwiKk5LOsDGNJbidKkLonV" + "W3APx32MsTMKAT6kkSqOmMyp2FYQb8x+1EYh114uXWJuaE5fhF9Hy8JWBOqVm52O"
+ "H6V+9m3gRqGbjgk6+t8jSvpA2Fs95AH7l9ocZ33IyvECgYEA49cH8/0GZzlgwPEb" + "RvA48Yj/62AaA0mdh0GkgadHJAJ5L3OW4FRZCUYKmwkoa/uF2MbVcR8cTqEawhNK"
+ "mVRd72e5gLBZurIA4NMxg4elJC00RJmElMO7ORX2tESr4NRJ0V+wJAaI/crLUahU" + "ZaUwg3xWn6Hea+rrVQhBLumhq28CgYEA3XleR0PRCO4RhnfdEKNLPfg99bDIdjiD"
+ "khoXpHBWHI/g08oA+g7SBv9c2SUnVkKQajr9K37fvXLyG8TDz0Ot901E/wEDaeY6" + "2yM52pz9aD1JTQFjzgMl5ppBpjClKiUL6QSKBsstKJUdtU/avCpuVs/twdMk8TmQ"
+ "lPSlAd6lX80CgYBYki44TmOf2zFesBwffqFUXCLI2KokHwkLHJyb/nBscj20EaZU" + "fNXEAiN7U5sQJ05IEDvHZwW1F3H0glVct+xwdg0qFuQ67JnkzJUSAbhUEPKhvGBL"
+ "CLAOqBgoyg1bMIulxiIOTzAQITba/qoYfZgXdU2jbuStZTyo6LWWTCKaJwKBgCCF" + "6ipc8x10mG4+u9/tmucGxVKHG2kA85FI85/aP0sCdemkCHCwLHeKmH/qzNQGAl8X"
+ "OoZgo0qWzqb1RivxrGJcnn00EOREQvBbQ+uukif0mAcO5TEjlTVAAdP94MNHnXAi" + "koJc48zJ2Qr/Jwfq0zk8X5XPA+XIpkq5gmG76F0hAoGAdl4VnqmRe84XB6sazwp1"
+ "4TfOKh73kAV4vO5II2Lv+wHQOk2CBYGInyYughxo1Y8yd7QlcwA2ydEcirZkpEgT" + "gdWmW2CPzZDYtGrgZY2yWD+AFotXq8uERkTEv9Z/90i51A5DdLPWSvF57dW8Xs9n"
+ "Xfp3W0N2LEVeJsbi7BhFvCU=";
public static void main(String[] args) throws UnsupportedEncodingException {
//生成公钥
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(pubKeySpec);
//生成私钥
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
String token = JWT.create().withClaim("key", "user-key") // jwt插件的key是作为jwt的载荷
.sign(Algorithm.RSA256(publicKey,privateKey));
System.out.println(token);
}
}
https测试
(1)外部https测试,即clinet到apisix这一段
(1) 自签名证书生成
生成自签名证书的私钥
openssl genrsa -out ca.key 2048
生成自签名证书(填写信息随意)
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
(2) 生成服务器私钥并签名服务器证书
生成服务器私钥
openssl genrsa -out server.key 2048
生成服务器证书请求
openssl req -new -key server.key -out server.csr
签名服务器证书
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
(3) 配置apisix.yaml
将server.key、server.crt的内容配置到/usr/local/apisix/conf/apisix.yaml中
ssl:
-
cert: |
-----BEGIN CERTIFICATE-----
MIIDGjCCAgICAQEwDQYJKoZIhvcNAQELBQAwUDELMAkGA1UEBhMCQ04xFTATBgNV
BAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDEM
MAoGA1UEAwwDU0tZMB4XDTIxMDYyMzEzNDkzN1oXDTIyMDYyMzEzNDkzN1owVjEL
MAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UECgwTRGVm
YXVsdCBDb21wYW55IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl+3MZYGAd6OXaljQqAuOKJfhxZfe8NBO4B9Q
r+l1xFbo2Zzz7Vq+v5aY36k4tCILfKFkrzeVK77QQ2W5QhHZY4Q0+B5L4Ty6mdcF
5uwrBjwTcbBskyYZVHoMU2gms69RkACZ6rIzAlzmJtAmDeKwKDYWgfv28FIKda8v
+R5eA9JVzUtK+VBTQuj4UA1skbs6McgmSdehrQcNN5MH9miUXMlu5X3wx5pIrUsG
L5yOTETLM/PaWRxHgOBX/neOLQ25TtVKwvGdnMU3OYe7qdifNDBrs+gGqVxAWRIy
5Ni7DRIzea3dS4NP4LS9QlLJAemeBaU4Ee1NXhKlMwTPYPdaCQIDAQABMA0GCSqG
SIb3DQEBCwUAA4IBAQAxi+KEk8oFjteK2hZPqHX0cmc68KGMf19bUqYaNWI/63H7
ksknsFJrGtT0ohd3fzxWNHRgkYOLBlYIXFBlboAmDSfTo6KIiFFxkQN4Yn8ptR7W
tkkqAleJbJt1avqCxRBoh2V9lA7XMvPHVaQ6s7PXOYQHAHXaYu7rCb/afoTTXIfJ
Hn8SLDTmnu+F1pSSbuyzETJDy0J5BBbCxECO+pmF3yomcz8xn6MBugv4VOzdIEbp
nHXbfw2p/u27dl/evTmkgeCamOGOusXHlgKT2GspmwEd+vnOlU8P6T0tmbJGSxP9
tPl/V3xlDm3YTq4NMXgc0nFi++S193AMBoB37X1I
-----END CERTIFICATE-----
key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAl+3MZYGAd6OXaljQqAuOKJfhxZfe8NBO4B9Qr+l1xFbo2Zzz
7Vq+v5aY36k4tCILfKFkrzeVK77QQ2W5QhHZY4Q0+B5L4Ty6mdcF5uwrBjwTcbBs
kyYZVHoMU2gms69RkACZ6rIzAlzmJtAmDeKwKDYWgfv28FIKda8v+R5eA9JVzUtK
+VBTQuj4UA1skbs6McgmSdehrQcNN5MH9miUXMlu5X3wx5pIrUsGL5yOTETLM/Pa
WRxHgOBX/neOLQ25TtVKwvGdnMU3OYe7qdifNDBrs+gGqVxAWRIy5Ni7DRIzea3d
S4NP4LS9QlLJAemeBaU4Ee1NXhKlMwTPYPdaCQIDAQABAoIBAGO0QlwnBaj+KgM3
sA9oLe4D5r2msj81ZV3+DxSy0H9+TadqMkaFNANFkKPPSRAl+4XZ4NqATpv7yG9C
lbZ/Qjvl6mEeeMui8A6/pvbp7D5WNKh6kHZtHVhsFCS0iBmJp6wqSNhWA9W8I6o7
FY4tQ0/QVysMsPz7yjN7Oa9yN16nqog6DiSbFyrIVCC2hwJIub1/n5g96Ts8x9wh
ME+EUC55/yeub9gczgQJ9ywXoRz8HyMcmkrzkFNcVoFcCmlVCJMjHrxbcCBlMM8L
kEGp0k3dgmao7z5ndjxmdkhCZHpfivCsNCWuqKU7uuLjuOwJR/NM6resEGnUwJ96
JDTykZUCgYEAyoU+prTw2GIHpPaCr9S/zDebFc+1f7JTTQw9q/sly8uuwzjN5PeY
bfLbpNEnn54U//yCgyTe/+sze3LMZ1HFfhu/tE7qeAga8VStbY8mk2YKS7PWByno
2zr4K7/PzZCHmfmintzKwIAS0frVQYfnSvGzvN5RijC5ICTsiea8uecCgYEAwAx4
Sq6Qxx8YlK5sSAKJIm4YAr7955GuQxntxRHw75vb29kU+aYio3sAjF+i8SQX4IGg
iJesJPqRWFeVS+g1MMm+TH/ubiIznSV/csHAK8VLCISGCBjJybkkO2CTvExt5uhl
1QZhGIqlqxMeb/Ll3e8u2s8YH0JLbZcHDa48Lo8CgYA/8E92bHv5pQGK2HUsNDwV
qpyhB0HjPhbEpY+3A4TMUdMsOXvvxSfv1pP39jzPTSaOJ1fBNdvd6pEHcZgNKqjy
hqpAsAWgvdZbyQM0KtTgBoBLpEx3WIj25ihCD734xZ+6QjFQfJ7apdTLTKkVlmW0
qJi5kWsm+PkJp/6yDxIYkwKBgQC84wblHTCUSAdbJPqnEKdkT7gZ61O7ENO+d6Ae
NfktEbR6VNaGfFqRRAdUCTQvzHoXfCcycUsEy9VseCgFEoxOQf6DK0iM1eLB6wGh
EuM5qcCUzhMtn4PIfeoe5GwpxVpKw8R0cuPIyYUL76/+F37ye68v0oQ9Km0ZinOL
hxT2DQKBgHROXMRraZVTyeqoMMTB45B3ludSkUKzw1Fq3DLQ5kHPT2Lu/ikWQggf
gWkTbAwAuspb0uCgY09HR/92pvZPLECRQzgpladcXlvFQNQfM419ItwBlzWEfrod
MfVbyJwM4XNfDEXvAU9S5fSbq5Ebd+c70qzp9MddlUuT+SHOXWmn
-----END RSA PRIVATE KEY-----
snis:
- "172.28.118.121" # 宿主机的ip,因为apisix是docker容器起来的
(2)内部https测试,即apisix到微服务这一段,和外部一样
测试Response转发
重写响应,也会覆盖Proxy转发过来的响应
测试Proxy转发
关闭重写响应体,为了看到转发的结果。如图
评论区