赞
踩
Spring Cloud Gateway 作为网关,通过用于执行一些通用逻辑后做请求转发,后端可能涉及到多个服务,每个服务又有多个实例,调用服务实例就需要动态的更新,可以通过注册中心来实现,如果部署在K8S集群中,可以直接使用K8S实现服务发现
plugins { id 'org.springframework.boot' version '2.2.6.RELEASE' id 'io.spring.dependency-management' version '1.0.9.RELEASE' id 'java' } ext { set('springCloudVersion', "Hoxton.SR1") set('springKubernetesVersion', "1.1.2.RELEASE") } dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-gateway' implementation 'org.springframework.cloud:spring-cloud-kubernetes-discovery' implementation 'org.springframework.boot:spring-boot-starter-actuator' testImplementation('org.springframework.boot:spring-boot-starter-test') { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' } } dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" mavenBom "org.springframework.cloud:spring-cloud-kubernetes-dependencies:${springKubernetesVersion}" } }
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-all'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-ribbon'
spring:
cloud:
kubernetes:
discovery:
catalogServicesWatchDelay: 5000
client:
master-url: https://kubernetes.docker.internal:6443
ca-cert-data: xxx
namespace: default
spring:
application.name: gateway
cloud:
gateway:
discovery:
locator:
enabled: true
url-expression: "'http://'+serviceId+':'+port"
lower-case-service-id: true
management:
endpoints:
web:
exposure:
include: '*'
配置 url-expression
目的是为了在转发的时候直接转发到 Kubernetes 中相应的 Service 上去,默认的表达式为 "'lb://'+serviceId"
,这种适用于通过 Consul 或者 Eureka,最终是根据服务的IP和端口访问,spring-cloud-kubernetes
没有实现com.netflix.loadbalancer.AbstractServerList
,所以不会进行IP转换,最终是通过服务名称查找Service 实现调用,所以不需要负载均衡
"'http://'+serviceId+':'+port"
通过 Gateway 调用后端的 API 应用,该应用提供 REST 接口
apiVersion: v1 kind: Service metadata: name: api namespace: default labels: app: api spec: type: ClusterIP ports: - port: 8080 selector: app: api --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: api name: api namespace: default spec: replicas: 1 selector: matchLabels: app: api template: metadata: labels: app: api spec: containers: - name: api image: registry.cn-qingdao.aliyuncs.com/hellowoodes/api:1.0.0 imagePullPolicy: IfNotPresent ports: - containerPort: 8080 name: http protocol: TCP
kubectl apply -f api.yaml
apiVersion: v1 kind: Service metadata: name: gateway namespace: default labels: app: gateway spec: type: NodePort ports: - port: 8080 nodePort: 30080 selector: app: gateway --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: gateway name: gateway namespace: default spec: replicas: 1 selector: matchLabels: app: gateway template: metadata: labels: app: gateway spec: containers: - name: gateway image: registry.cn-qingdao.aliyuncs.com/hellowoodes/api-gateway:1.0.6 imagePullPolicy: IfNotPresent ports: - containerPort: 8080 name: http protocol: TCP
kubectl apply -f gateway.yaml
http get localhost:30080/actuator/gateway/routes
http get localhost:30080/api/hello
这里会根据 api
这个path 查找名为 api
的 Service,然后调用 http://api:8080/hello
,这个接口返回hostname,也就是pod的名称
启动多个 API 服务实例
kubectl scale --replicas=2 deploy/api
待服务启动后多次调用http://localhost:30080/api/hello
,返回的pod名称会变化,说明负载均衡生效
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。