Spring Cloud Zuul网关搭建详解

网关的英文名称:gateway,又叫做网间连接器、协议转换器。网关是在采用不同体系结构或协议的网络之间进行互通时,用于提供协议转换、路由选择、数据交换、日志埋点、负载均衡、容灾、鉴权、限流等网络兼容功能的设施。

Spring Cloud Zuul网关搭建详解_第1张图片

后台服务肯定不能暴露在外,而且都是内网,这里的网关就至关重要,为了防止单点故障,实现高可用。可以搭建多节点

springboot2.1.1 springcloud Finchley.RELEASE版本,第一次使用spring boot这么高的版本

创建一个spring boot项目,搭建过程也很简单

构建时通过maven project module方式构建的

父pom.xml:


	4.0.0
	com.chwl.cn
	chwl
	0.0.1-SNAPSHOT
	pom

	
		UTF-8
		1.8
		1.8
		4.12
		1.2.17
		1.16.18
	

	
		
			
				org.springframework.cloud
				spring-cloud-dependencies
				Finchley.RELEASE
				pom
				import
			
			
				org.springframework.boot
				spring-boot-dependencies
				2.1.1.RELEASE
				pom
				import
			
			
				mysql
				mysql-connector-java
				
				8.0.11
			
			
				com.alibaba
				druid
				1.0.31
			
			
				org.mybatis.spring.boot
				mybatis-spring-boot-starter
				1.3.0
			
			
				ch.qos.logback
				logback-core
				1.2.3
			
			
				junit
				junit
				${junit.version}
				test
			
			
				org.apache.httpcomponents
				httpclient
				4.5.4
			
			
				org.apache.commons
				commons-lang3
				3.1
			
		
	

	
	
		chwl-eureka-server
		chwl-entity
		chwl-common
		chwl-provider-order
		chwl-provider-product
		chwl-api-gateway-zuul-7001
	

zuul  pom.xml依赖:


			org.springframework.cloud
			spring-cloud-starter-netflix-eureka-client
		
		
			org.springframework.cloud
			spring-cloud-starter-netflix-zuul
		

启动类:添加@EnableZuulProxy注解

package com.chwl.cn;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@EnableZuulProxy
@EnableEurekaClient
@SpringBootApplication
public class APIGatewayApplication {
	public static void main(String[] args) {
		SpringApplication.run(APIGatewayApplication.class, args);
	}
}

@EnableZuulProxy默认集成了hystrix熔断器@EnableCircuitBreaker

源码:

 * Copyright 2013-2017 the original author or authors.

package org.springframework.cloud.netflix.zuul;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.context.annotation.Import;

/**
 * Sets up a Zuul server endpoint and installs some reverse proxy filters in it, so it can
 * forward requests to backend servers. The backends can be registered manually through
 * configuration or via DiscoveryClient.
 *
 * @see EnableZuulServer for how to get a Zuul server without any proxying
 *
 * @author Spencer Gibb
 * @author Dave Syer
 * @author Biju Kunjummen
 */
@EnableCircuitBreaker
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(ZuulProxyMarkerConfiguration.class)
public @interface EnableZuulProxy {
}

application.yml:

server: 
  port: 7001
#服务的名称
spring:
  application:
    name: chwl-api-gateway-zuul-7001
#  main:
#    allow-bean-definition-overriding: true
    
eureka: 
  client: #客户端注册进eureka服务列表内
    service-url: 
      #defaultZone: http://localhost:2001/eureka    #这个地址就是EurekaServer注册中心的地址
       defaultZone: http://ypp:[email protected]:2001/eureka/,http://ypp:[email protected]:2002/eureka/
  instance: 
    instance-id: chwl-api-gateway-zuul-7001
    prefer-ip-address: true     #访问路径可以显示IP地址
    
#自定义路由映射    
zuul: 
  routes: 
    chwl-provider-product: /apigateway/**
    chwl-provider-order: /apigateway/**
  #统一入口为上面的配置,其他入口忽略
  ignored-patterns: /*-provider-*/**
  #忽略整个服务,对外提供接口
  #ignored-services: chwl-provider-product

如果不需要自定义路由映射,可以不要zuul那几项配置,默认的规则是 host:port/spring:application:name/uri

比如商品服务访问就是:localhost:9001/chwl-provider-product/product/get/1

商品服务application.yml:

server: 
  port: 8003
#开启断路器,Feign接口API的实现类方法处理   
feign: 
  hystrix:
    enabled: true
    
hystrix:
  command:
    default:  #default全局有效,service id指定应用有效
      execution:
        timeout:
          #如果enabled设置为false,则请求超时交给ribbon控制,为true,则超时作为熔断根据
          enabled: true
        isolation:
          thread:
            timeoutInMilliseconds: 3000 #断路器超时时间,默认1000ms
    
spring: 
  application: 
    name: chwl-provider-product         #很重要,很重要,很重要,这是微服务向外部暴露的微服务的名字
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    platform: mysql
    url: jdbc:mysql://120.79.81.103:5306/chwl?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false
    username: root
    password: admin
  redis: 
#    database: 1
    host: 127.0.0.1
    port: 6379
    password: 
    timeout: 10000
    lettuce:
          pool:
            minIdle: 0
            maxIdle: 10
            maxWait: 10000
            max-active: 10
    sentinel:
      master: master-6379
      nodes: 127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381
#    cluster:
#      nodes:
#        - 192.168.91.5:9001
#        - 192.168.91.5:9002
#        - 192.168.91.5:9003
#        - 192.168.91.5:9004
#        - 192.168.91.5:9005
#        - 192.168.91.5:9006
    
mybatis: 
  config-location: classpath:mybatis/mybatis.cfg.xml
  #typeAliasesPackage: com.ypp.springcloud.entites
  mapper-locations: classpath:mybatis/mapper/**/*Mapper.xml
mapper:
  mappers: com.chwl.cn.basemapper.BaseMapper
  identity: mysql
  
eureka:
  client: #客户端注册进eureka服务列表内
    service-url: 
      #defaultZone: http://localhost:2001/eureka    #这个地址就是EurekaServer注册中心的地址
       defaultZone: http://ypp:[email protected]:2001/eureka/,http://ypp:[email protected]:2002/eureka/
  instance: 
    instance-id: chwl-provider-product
    prefer-ip-address: true     #访问路径可以显示IP地址

如果自定义路由映射,那么会存在一个问题。

/apigateway/product/xx/xx

/chwl-provider-product/product/xx/xx

2种路由都可以进行。

所以我们一般忽略本身的,忽略chwl-provider-product等。

统一使用apigateway的方式:

#统一入口为上面的配置,其他入口忽略
  ignored-patterns: /*-provider-*/**

那么现在只能通过/gateway/product/xx/xxx/xx的方式进行访问

最终的项目结构:

Spring Cloud Zuul网关搭建详解_第2张图片

启动报错:

Description:

The bean 'proxyRequestHelper', defined in class path resource [org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfiguration$NoActuatorConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfiguration$EndpointConfiguration.class] and overriding is disabled.

Action:

Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

一种说法是版本springcloud和springboot版本不一致,更换版本也有可能解决。

还有可能原因是因为类名和某些方法名重复了,提示已经很明显,让重新设置一个bean(意思修改类名或方法名)或设置spring.main.allow-bean-definition-overriding=true允许spring进行覆盖。没有找到哪里重复了,更换版本出错的几率有点大,因为要更换版本又容易造成版本不一致,暂时解决先设置spring.main.allow-bean-definition-overriding=true

在application.yml添加配置:spring.main.allow-bean-definition-overriding=true

Spring Cloud Zuul网关搭建详解_第3张图片

启动继续报错:

Description:

An attempt was made to call the method org.springframework.boot.autoconfigure.web.ServerProperties$Servlet.getServletPrefix()Ljava/lang/String; but it does not exist. Its class, org.springframework.boot.autoconfigure.web.ServerProperties$Servlet, is available from the following locations:

    jar:file:/E:/java/repository/org/springframework/boot/spring-boot-autoconfigure/2.1.1.RELEASE/spring-boot-autoconfigure-2.1.1.RELEASE.jar!/org/springframework/boot/autoconfigure/web/ServerProperties$Servlet.class

It was loaded from the following location:

    file:/E:/java/repository/org/springframework/boot/spring-boot-autoconfigure/2.1.1.RELEASE/spring-boot-autoconfigure-2.1.1.RELEASE.jar


Action:

Correct the classpath of your application so that it contains a single, compatible version of org.springframework.boot.autoconfigure.web.ServerProperties$Servlet

一看就是jar冲突了

然后发现是spring boot和spring cloud版本不一致造成。网上的解决办法是spring boot 2.1.1.RELEASE版本对应的是spring cloud Greenwich.M3版本,修改了,然而并没有什么卵用,maven根本没有相关依赖。然后翻官网没找到相关对应的版本信息。然后试了一下spring cloud Greenwich.RELEASE的版本。成功,取消之前的spring.main.allow-bean-definition-overriding=true。

第一次使用spring 2.1.1版本,依赖也变了,问题出现的早,还好花了几分钟解决了,慢慢熟悉高版本

zuul测试

Spring Cloud Zuul网关搭建详解_第4张图片

使用localhost:7001/chwl-provider-order/  失败

Spring Cloud Zuul网关搭建详解_第5张图片

 

网关自定义路由配置成功了,

问题一:直接使用微服务的地址和端口加路径是可以访问的。但这种情况在应用生产部署基本是内外网隔离的,别人是访问不到的,也不知道到底是哪台服务器。只有通过网关统一入口进行访问

问题二:以下自定义路由配置product和order服务都是使用的apigateway统一访问的,会产生一个问题。后面的会覆盖前面的,所以product的服务是完全访问不了,会提示404,因为ignored-patterns: /*-provider-*/**也把它给忽略了

#自定义路由映射    
zuul: 
  routes: 
    chwl-provider-product: /apigateway/**
    chwl-provider-order: /apigateway/**
  #统一入口为上面的配置,其他入口忽略
  ignored-patterns: /*-provider-*/**
  #忽略整个服务,对外提供接口
  #ignored-services: chwl-provider-product

改造后:

#自定义路由映射    
zuul: 
  routes: 
    chwl-provider-product: /apigateway/product/**
    chwl-provider-order: /apigateway/order/**
  #统一入口为上面的配置,其他入口忽略
  ignored-patterns: /*-provider-*/**
  #忽略整个服务,对外提供接口
  #ignored-services: chwl-provider-product

测试:

网关配置完成

代码已上传github,包括feign、hystrix、ribbon、eureka等      https://github.com/yfcgklypp/chwl.git

你可能感兴趣的:(Spring,Cloud,Spring,Boot,微服务)