spring-cloud / spring-cloud-netflix

Integration with Netflix OSS components
http://cloud.spring.io/spring-cloud-netflix/
Apache License 2.0
4.86k stars 2.44k forks source link

invoke service using ribbon slowly first time, second time is so fast #2936

Closed liyinsong closed 5 years ago

liyinsong commented 6 years ago

I'm getting read timeout for a service that is taking a long time and throw the socket timeout exception, but next time call the same service very fast. Then i change the timeout time and disable the hystrix timeout like below:

ribbon:
  ConnectTimeout: 300000
  ReadTimeout: 300000
hystrix:
    command:
        default:
            execution:
                timeout:
                    enabled: false

Now there is no exception but also takes a long time to call the servcie, also the next invoke it's fast. So i change the ribbon load to the eager-load strategy, but also have the same problem.

ribbon:
      eager-load:
        enabled: true

The version is Dalston.SR4, can your guys give me some suggests?

ryanjbaxter commented 6 years ago

Please learn how to format code on GitHub.

The first think I would suggest is trying Edgware.SR3. At the very least you would want to be using Dalston.SR5.

Also I think you need to specify the clients you want to eager load http://cloud.spring.io/spring-cloud-static/Edgware.SR3/single/spring-cloud.html#ribbon-child-context-eager-load

liyinsong commented 6 years ago

Thks, i will try it.

liyinsong commented 6 years ago

I updated the version to Edgware.SR3. Also have the same issue...

yml config:

ribbon:
  eager-load:
    enabled: true
    clients: ServiceA
  ConnectTimeout: 300000
  ReadTimeout: 300000

hystrix:
    command:
        default:
            execution:
                timeout:
                    enabled: false

eureka:
    instance:
        prefer-ip-address: true
        lease-renewal-interval-in-seconds: 30
        lease-expiration-duration-in-seconds: 90
    client:
        serviceUrl:
            defaultZone: http://localhost:9000/eureka/
ryanjbaxter commented 6 years ago

Could you put together a sample that demonstrates the problem?

liyinsong commented 6 years ago

@ryanjbaxter There have two services, serviceA to invoke the serviceB,

ServiceA:

@Service
public class ServiceA {
   @Autowired
    private RemoteServiceB serviceB;

    public void test() {
          //print log
      serviceB.find();
   }
}

API:

@FeignClient(name= "serviceB")
@RequestMapping("/service/serviceB")
public interface RemoteServiceB{

    @RequestMapping(value = "/find", method = RequestMethod.POST)
        Result<User> find();
}

servie B:

@RestController
public class UserRestController {

    @RequestMapping(value = "/service/serviceB/find", method = RequestMethod.POST)
    Result<User> find(){
        //do something
    }
}

Eureka server config:

server:
    port: 9000
    tomcat:
        uri-encoding: UTF-8

eureka:
    server:
        enable-self-preservation: false
    instance:
        hostname: springcloud-registry
        prefer-ip-address: true
    client:
        register-with-eureka: false
        fetch-registry: false
        serviceUrl:
            defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

service A yml config:

spring:
    application:
        name: serviceA
    profiles:
        active: dev
    aop:
        proxy-target-class: true
server:
    port: 8090
    tomcat:
        uri-encoding: UTF-8
eureka:
    instance:
        prefer-ip-address: true
        lease-renewal-interval-in-seconds: 30
        lease-expiration-duration-in-seconds: 90
    client:
        serviceUrl:
            defaultZone: http://springcloud-registry:9000/eureka/

ribbon:
  eager-load:
    enabled: true
    clients: serviceB
  ConnectTimeout: 300000
  ReadTimeout: 300000

hystrix:
    command:
        default:
            execution:
                timeout:
                    enabled: false

service B yml config:

spring:
    application:
        name: serviceB
    profiles:
        active: dev
    aop:
        proxy-target-class: true
eureka:
    instance:
        prefer-ip-address: true
        lease-renewal-interval-in-seconds: 30
        lease-expiration-duration-in-seconds: 90
    client:
        serviceUrl:
            defaultZone: http://springcloud-registry:9000/eureka/

ribbon:
  ConnectTimeout: 300000
  ReadTimeout: 300000

hystrix:
    command:
        default:
            execution:
                timeout:
                    enabled: false

This is the sample like above. And ServiceA.test() has print log before call the servcie B, but it takes a long time to invoke serviceB...

ryanjbaxter commented 6 years ago

Put the sample in a git repo or attach it as a zip

spring-projects-issues commented 5 years ago

Closing due to age of the question. If you would like us to look at this issue, please comment and we will look at re-opening the issue.