com.xyxy.platform.examples.showcase.demos.hystrix.service.UserService.java Source code

Java tutorial

Introduction

Here is the source code for com.xyxy.platform.examples.showcase.demos.hystrix.service.UserService.java

Source

/*******************************************************************************
 * Copyright (c) 2005, 2014
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *******************************************************************************/
package com.xyxy.platform.examples.showcase.demos.hystrix.service;

import java.util.HashMap;

import javax.annotation.PostConstruct;

import com.xyxy.platform.examples.showcase.webservice.rest.UserDTO;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.netflix.hystrix.HystrixCircuitBreaker;
import com.netflix.hystrix.HystrixCommand.Setter;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandMetrics;
import com.netflix.hystrix.HystrixCommandMetrics.HealthCounts;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.HystrixCommandProperties.ExecutionIsolationStrategy;
import com.netflix.hystrix.HystrixThreadPoolProperties;
import com.netflix.hystrix.util.HystrixRollingNumberEvent;

/**
 * Hystrix ?Service?restTemplateHystrix Command?.
 * 
 *
 */
@Service
public class UserService {

    private boolean isolateThreadPool = true;
    private Setter commandConfig;
    private RestTemplate restTemplate;

    /**
     * command, ??Hystrix Error?Web.
     */
    public UserDTO getUser(Long id) throws Exception {
        GetUserCommand command = new GetUserCommand(commandConfig, restTemplate, id);
        return command.execute();
    }

    /**
     * ?HystrixMetrics.
     */
    public MetricsMap getHystrixMetrics() {
        MetricsMap metricsMap = new MetricsMap();
        HystrixCommandKey key = HystrixCommandKey.Factory.asKey("GetUserCommand");
        HystrixCommandMetrics metrics = HystrixCommandMetrics.getInstance(key);

        if (metrics != null) {
            HealthCounts counts = metrics.getHealthCounts();
            HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory.getInstance(key);

            metricsMap.put("circuitOpen", circuitBreaker.isOpen());
            metricsMap.put("totalRequest", counts.getTotalRequests());
            metricsMap.put("errorPercentage", counts.getErrorPercentage());
            metricsMap.put("success", metrics.getRollingCount(HystrixRollingNumberEvent.SUCCESS));
            metricsMap.put("timeout", metrics.getRollingCount(HystrixRollingNumberEvent.TIMEOUT));
            metricsMap.put("failure", metrics.getRollingCount(HystrixRollingNumberEvent.FAILURE));
            metricsMap.put("shortCircuited", metrics.getRollingCount(HystrixRollingNumberEvent.SHORT_CIRCUITED));
            metricsMap.put("threadPoolRejected",
                    metrics.getRollingCount(HystrixRollingNumberEvent.THREAD_POOL_REJECTED));
            metricsMap.put("semaphoreRejected",
                    metrics.getRollingCount(HystrixRollingNumberEvent.SEMAPHORE_REJECTED));
            metricsMap.put("latency50", metrics.getTotalTimePercentile(50));
            metricsMap.put("latency90", metrics.getTotalTimePercentile(90));
            metricsMap.put("latency100", metrics.getTotalTimePercentile(100));
        }

        return metricsMap;
    }

    /**
     * Hystrix Command???, Thread-SafedRestTemplate.
     */
    @PostConstruct
    public void init() {
        // ?RestTemplate
        restTemplate = new RestTemplate();

        // Command?? //
        commandConfig = Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
                .andCommandKey(HystrixCommandKey.Factory.asKey("GetUserCommand"));

        HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter();
        commandConfig.andCommandPropertiesDefaults(commandProperties);

        //  //
        // ?? 520
        commandProperties.withCircuitBreakerSleepWindowInMilliseconds(20000)
                // rolling windows?50%?.
                .withCircuitBreakerErrorThresholdPercentage(50)
                // rolling window???20, 3.
                .withCircuitBreakerRequestVolumeThreshold(3)
                // rolling windows 20120???.
                .withMetricsRollingStatisticalWindowInMilliseconds(120000)
                .withMetricsRollingStatisticalWindowBuckets(120);

        // ? //
        if (isolateThreadPool) { // Hystrix
            // 13.
            commandProperties.withExecutionIsolationThreadTimeoutInMilliseconds(3000);
            //  ?10??5?.
            commandConfig.andThreadPoolPropertiesDefaults(
                    HystrixThreadPoolProperties.Setter().withCoreSize(10).withQueueSizeRejectionThreshold(5));
        } else { // 
            // ??RestTemplate10
            ((SimpleClientHttpRequestFactory) restTemplate.getRequestFactory()).setReadTimeout(10000);

            // ?10?.
            commandProperties.withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE)
                    .withExecutionIsolationSemaphoreMaxConcurrentRequests(10);
        }
    }

    public void setIsolateThreadPool(boolean isolateThreadPool) {
        this.isolateThreadPool = isolateThreadPool;
    }

    /**
     * Map?0.
     */
    public static class MetricsMap extends HashMap {
        @Override
        public Object get(Object key) {
            Object result = super.get(key);
            return result != null ? result : "0";
        }
    }
}