Error when Zuul routing to a HTTPS url

梦想的初衷 提交于 2019-11-30 18:08:36

问题


I have a Spring Boot application (recently enabled it for HTTPS + self signed certificate) which is registered in Eureka and visible in the Eureka dashboard.

We have a Zuul Filter layer which gets the user request and then passes it on to the Spring Boot application. This was working fine until the app was accessible via HTTP. But, once i enabled HTTPS, the zuul routing is failing.

Here is the Zuul route configuration in my yaml file. Should my Zuul Route configuration have any special configuration for HTTPS enabled URL/App ?

zuul:
  routes:
    ms:
       path: /app/**
       stripPrefix: true

    ms:   
      ribbon:
        ServerListRefreshInterval: 1000
        ConnectTimeout: 20000
        ReadTimeout: 20000

Here is the exception stack trace (showing that Zuul is trying to route to the HTTP URL , instead of the HTTPS url)

Caused by: com.netflix.hystrix.exception.HystrixRuntimeException: msRibbonCommand failed and no fallback available.
    at com.netflix.hystrix.AbstractCommand$20.call(AbstractCommand.java:816) ~[hystrix-core-1.4.0-RC6.jar:na]
    at com.netflix.hystrix.AbstractCommand$20.call(AbstractCommand.java:798) ~[hystrix-core-1.4.0-RC6.jar:na]
    at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$1.onError(OperatorOnErrorResumeNextViaFunction.java:76) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:70) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:70) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$ThrowObservable$1.call(Observable.java:10493) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$ThrowObservable$1.call(Observable.java:10483) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable.unsafeSubscribe(Observable.java:8591) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$1.onError(OperatorOnErrorResumeNextViaFunction.java:77) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.OperatorMap$1.onError(OperatorMap.java:48) ~[rxjava-core-0.20.7.jar:na]
    at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:318) ~[hystrix-core-1.4.0-RC6.jar:na]
    at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:310) ~[hystrix-core-1.4.0-RC6.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable.unsafeSubscribe(Observable.java:8591) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$1.onError(OperatorOnErrorResumeNextViaFunction.java:77) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:70) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.OperatorMap$1.onError(OperatorMap.java:48) ~[rxjava-core-0.20.7.jar:na]
    at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$3.onError(AbstractCommand.java:995) ~[hystrix-core-1.4.0-RC6.jar:na]
    at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:70) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:70) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$ThrowObservable$1.call(Observable.java:10493) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$ThrowObservable$1.call(Observable.java:10483) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable.unsafeSubscribe(Observable.java:8591) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$1.onError(OperatorOnErrorResumeNextViaFunction.java:77) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.OperatorMap$1.onError(OperatorMap.java:48) ~[rxjava-core-0.20.7.jar:na]
    at com.netflix.hystrix.HystrixCommand$1.call(HystrixCommand.java:301) ~[hystrix-core-1.4.0-RC6.jar:na]
    at com.netflix.hystrix.HystrixCommand$1.call(HystrixCommand.java:293) ~[hystrix-core-1.4.0-RC6.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable.unsafeSubscribe(Observable.java:8591) ~[rxjava-core-0.20.7.jar:na]
    at com.netflix.hystrix.AbstractCommand$1.call(AbstractCommand.java:388) ~[hystrix-core-1.4.0-RC6.jar:na]
    at com.netflix.hystrix.AbstractCommand$1.call(AbstractCommand.java:368) ~[hystrix-core-1.4.0-RC6.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable.unsafeSubscribe(Observable.java:8591) ~[rxjava-core-0.20.7.jar:na]
    at com.netflix.hystrix.AbstractCommand$ObservableCommand$1.call(AbstractCommand.java:1097) ~[hystrix-core-1.4.0-RC6.jar:na]
    at com.netflix.hystrix.AbstractCommand$ObservableCommand$1.call(AbstractCommand.java:1093) ~[hystrix-core-1.4.0-RC6.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable.subscribe(Observable.java:8680) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.BlockingOperatorToFuture.toFuture(BlockingOperatorToFuture.java:55) ~[rxjava-core-0.20.7.jar:na]
    at rx.observables.BlockingObservable.toFuture(BlockingObservable.java:420) ~[rxjava-core-0.20.7.jar:na]
    at com.netflix.hystrix.HystrixCommand.queue(HystrixCommand.java:385) ~[hystrix-core-1.4.0-RC6.jar:na]
    at com.netflix.hystrix.HystrixCommand.execute(HystrixCommand.java:339) ~[hystrix-core-1.4.0-RC6.jar:na]
    at org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter.forward(RibbonRoutingFilter.java:130) ~[spring-cloud-netflix-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
    ... 82 common frames omitted
Caused by: com.netflix.client.ClientException: null
    at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:123) ~[ribbon-loadbalancer-2.0-RC13.jar:na]
    at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:81) ~[ribbon-loadbalancer-2.0-RC13.jar:na]
    at org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand.forward(RibbonCommand.java:129) ~[spring-cloud-netflix-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
    at org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand.run(RibbonCommand.java:103) ~[spring-cloud-netflix-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
    at org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand.run(RibbonCommand.java:1) ~[spring-cloud-netflix-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
    at com.netflix.hystrix.HystrixCommand$1.call(HystrixCommand.java:298) ~[hystrix-core-1.4.0-RC6.jar:na]
    ... 125 common frames omitted
Caused by: org.apache.http.client.ClientProtocolException: null
    at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:867) ~[httpclient-4.3.6.jar:4.3.6]
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:115) ~[httpclient-4.3.6.jar:4.3.6]
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57) ~[httpclient-4.3.6.jar:4.3.6]
    at com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle(ApacheHttpClient4Handler.java:170) ~[jersey-apache-client4-1.11.jar:1.11]
    at com.sun.jersey.api.client.Client.handle(Client.java:648) ~[jersey-client-1.13.jar:1.13]
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:680) ~[jersey-client-1.13.jar:1.13]
    at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74) ~[jersey-client-1.13.jar:1.13]
    at com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:568) ~[jersey-client-1.13.jar:1.13]
    at com.netflix.niws.client.http.RestClient.execute(RestClient.java:621) ~[ribbon-httpclient-2.0-RC13.jar:na]
    at com.netflix.niws.client.http.RestClient.execute(RestClient.java:527) ~[ribbon-httpclient-2.0-RC13.jar:na]
    at com.netflix.niws.client.http.RestClient.execute(RestClient.java:92) ~[ribbon-httpclient-2.0-RC13.jar:na]
    at com.netflix.client.AbstractLoadBalancerAwareClient$1.call(AbstractLoadBalancerAwareClient.java:109) ~[ribbon-loadbalancer-2.0-RC13.jar:na]
    at com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:303) ~[ribbon-loadbalancer-2.0-RC13.jar:na]
    at com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:287) ~[ribbon-loadbalancer-2.0-RC13.jar:na]
    at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:54) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:41) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:30) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable.unsafeSubscribe(Observable.java:8591) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.OperatorConcat$ConcatSubscriber.subscribeNext(OperatorConcat.java:163) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.OperatorConcat$ConcatSubscriber.onNext(OperatorConcat.java:128) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.OperatorConcat$ConcatSubscriber.onNext(OperatorConcat.java:65) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:54) ~[rxjava-core-0.20.7.jar:na]
    at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:185) ~[ribbon-loadbalancer-2.0-RC13.jar:na]
    at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180) ~[ribbon-loadbalancer-2.0-RC13.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable.unsafeSubscribe(Observable.java:8591) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber$1.call(OperatorRetryWithPredicate.java:112) ~[rxjava-core-0.20.7.jar:na]
    at rx.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.enqueue(TrampolineScheduler.java:85) ~[rxjava-core-0.20.7.jar:na]
    at rx.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.schedule(TrampolineScheduler.java:65) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:77) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:45) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:41) ~[rxjava-core-0.20.7.jar:na]
    at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:30) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:173) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable$2.call(Observable.java:166) ~[rxjava-core-0.20.7.jar:na]
    at rx.Observable.subscribe(Observable.java:8680) ~[rxjava-core-0.20.7.jar:na]
    at rx.observables.BlockingObservable.blockForSingle(BlockingObservable.java:452) ~[rxjava-core-0.20.7.jar:na]
    at rx.observables.BlockingObservable.single(BlockingObservable.java:348) ~[rxjava-core-0.20.7.jar:na]
    at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:102) ~[ribbon-loadbalancer-2.0-RC13.jar:na]
    ... 130 common frames omitted
Caused by: org.apache.http.ProtocolException: The server failed to respond with a valid HTTP response
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:151) ~[httpclient-4.3.6.jar:4.3.6]
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57) ~[httpclient-4.3.6.jar:4.3.6]
    at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:261) ~[httpcore-4.4.jar:4.4]
    at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:283) ~[httpcore-4.4.jar:4.4]
    at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:251) ~[httpclient-4.3.6.jar:4.3.6]
    at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:223) ~[httpclient-4.3.6.jar:4.3.6]
    at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:272) ~[httpcore-4.4.jar:4.4]
    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:124) ~[httpcore-4.4.jar:4.4]
    at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:685) ~[httpclient-4.3.6.jar:4.3.6]
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:487) ~[httpclient-4.3.6.jar:4.3.6]
    at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:863) ~[httpclient-4.3.6.jar:4.3.6]

Update: After adding the isRibbon secure property, this error was gone and now i have a new error.


回答1:


It has been a little while since I have played with this because we ended up not being able to use it due to the limitation of not being able to pass the users certificate through the proxy. However, you asked for my help, so I'll try to share what I did have working.

I was able to get 2-way SSL working between both the ZUUL, acting as an Edge Server, and the Services on the backend while running in their own VMs (i.e. doing a mvn spring-boot:run on each service).

Here is my Zuul Conifg:

info:
  component: Zuul Server

endpoints:
  restart:
    enabled: true
  shutdown:
    enabled: true
  health:
    sensitive: false

zuul:
  routes:
    ui: /**
    api: /api/**

logging:
  level:
    ROOT: INFO
    org.springframework.web: DEBUG

server:
  port: 8443
  ssl:
      key-store: classpath:dev/localhost.jks
      key-store-password: yourpassword
      keyStoreType: JKS
      keyAlias: localhost
      clientAuth: want
      trust-store: classpath:dev/localhost.jks

ribbon:
    IsSecure: true

The Edge Server itself is nothing interesting:

@SpringBootApplication
@Controller
@EnableAutoConfiguration
@EnableZuulProxy
public class ZuulEdgeServer {
    public static void main(String[] args) {
        new SpringApplicationBuilder(ZuulEdgeServer.class).web(true).run(args);
    }
}

Now in my other services I had the following in their application.yml files:

server:
  port: 8444
  ssl:
      key-store: classpath:dev/localhost.jks
      key-store-password: yourpassword
      keyStoreType: JKS
      keyAlias: localhost
      clientAuth: want
      trust-store: classpath:dev/localhost.jks

eureka:
  instance: 
    nonSecurePortEnabled: false
    securePortEnabled: true
    securePort: ${server.port}
    homePageUrl: https://${eureka.instance.hostname}:${server.port}/
    secureVirtualHostName: ${spring.application.name}

My Eureka Config doesn't have much too it, but just in case:

server:
  port: 8761

eureka:
  client:
    registerWithEureka: false
    fetchRegistry: false
  server:
    waitTimeInMsWhenSyncEmpty: 0

My bootstrap.yml's in most the applications look like this:

spring:
  application:
    name: eureka
  cloud:
    config:
      uri: ${vcap.services.${PREFIX:}configserver.credentials.uri:http://user:password@localhost:8888}

I mainly found I needed the spring.application.name in there to resolve conflicts when running the applications within the same container.

If I remember right, the important parts from above were:

  • ribbon.isSecure = true in the zuul config
  • eureka.instance.securePortEnabled = true and the securePort in the backend services.

I can't remember if the secureVirtualHostName was important or not.

Hopefully this info can help you out though!



来源:https://stackoverflow.com/questions/32478146/error-when-zuul-routing-to-a-https-url

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!