| 
			
	
	
	
						  
						
						
						
	
 步骤 2 : 模仿和排错 步骤 3 : 模拟回测微服务 步骤 4 : 拓扑图点亮 步骤 5 : 创建子模块 步骤 6 : pom.xml 步骤 7 : application.yml 步骤 8 : IndexData.java 步骤 9 : IndexDataClient 步骤 10 : IndexDataClientFeignHystrix 步骤 11 : BackTestService 步骤 12 : BackTestController 步骤 13 : TrendTradingBackTestServiceApplication 步骤 14 : 测试 
					老规矩,先下载右上角的可运行项目,配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。  
					
				先启动 EurekaServerApplication 然后启动 IndexDataApplication 最后启动 TrendTradingBackTestServiceApplication 注: 记得运行redis-server.exe 以启动 redis 服务器 访问地址: http://127.0.0.1:8051/simulate/000300 
					在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。 
 
					
				模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较正确答案 ( 可运行项目 ) 和自己的代码,来定位问题所在。 采用这种方式,学习有效果,排错有效率,可以较为明显地提升学习速度,跨过学习路上的各个槛。 推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。 这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来 这里提供了绿色安装和使用教程:diffmerge 下载和使用教程 
					在模拟回测视图那里需要很多的数据,这些数据都是从这个模拟回测服务里产生的。 虽然现在看上去只有单纯的指数原数据,但是随着业务的增加,功能的迭代,会有越来越丰富的数据产生出来啦。
					 
					
				
					创建子模块: trend-trading-backtest-service
					 
					
				
					比起以前的多了一个 spring-cloud-starter-openfeign jar 用于启动 Feign 方式访问其他微服务。
					 
					
				<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>cn.how2j.trend</groupId>
        <artifactId>trendParentProject</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>trend-trading-backtest-service</artifactId>
    <dependencies>
        <!-- springboot web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- eureka-client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!-- feign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- 断路器 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
    </dependencies>
</project>
 
								
										
									
								
							eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
spring:
  application:
    name:  trend-trading-backtest-service
feign.hystrix.enabled: true
 
									
								eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
spring:
  application:
    name:  trend-trading-backtest-service
feign.hystrix.enabled: true
								
								package cn.how2j.trend.pojo;
public class IndexData {
	String date;
	float closePoint;
	public String getDate() {
		return date;
	}
	public void setDate(String date) {
		this.date = date;
	}
	public float getClosePoint() {
		return closePoint;
	}
	public void setClosePoint(float closePoint) {
		this.closePoint = closePoint;
	}
	
}
 
									
								package cn.how2j.trend.pojo;
public class IndexData {
	String date;
	float closePoint;
	public String getDate() {
		return date;
	}
	public void setDate(String date) {
		this.date = date;
	}
	public float getClosePoint() {
		return closePoint;
	}
	public void setClosePoint(float closePoint) {
		this.closePoint = closePoint;
	}
	
}
								
								
					使用 feign 模式从 INDEX-DATA-SERVICE 微服务获取数据。  
					
				与之前使用的 RestTemplate 方式不同,这里是声明式的。 fallback = IndexDataClientFeignHystrix.class) 这句话表示访问不了的时候,就去找 IndexDataClientFeignHystrix 要数据了。 package cn.how2j.trend.client;
import java.util.List;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import cn.how2j.trend.pojo.IndexData;
@FeignClient(value = "INDEX-DATA-SERVICE",fallback = IndexDataClientFeignHystrix.class)
public interface IndexDataClient {
    @GetMapping("/data/{code}")
    public List<IndexData> getIndexData(@PathVariable("code") String code);
}
 
									
								package cn.how2j.trend.client;
import java.util.List;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import cn.how2j.trend.pojo.IndexData;
@FeignClient(value = "INDEX-DATA-SERVICE",fallback = IndexDataClientFeignHystrix.class)
public interface IndexDataClient {
    @GetMapping("/data/{code}")
    public List<IndexData> getIndexData(@PathVariable("code") String code);
}
								
								
					IndexDataClientFeignHystrix  实现了 IndexDataClient,所以就提供了对应的方法,当熔断发生的时候,对应的方法就会被调用了。 
					
				这里的方法就是指如果 INDEX-DATA-SERVICE 不可用或者不可访问,就会返回个 0000-00-00 出去啦。 package cn.how2j.trend.client;
import java.util.List;
import org.springframework.stereotype.Component;
import cn.how2j.trend.pojo.IndexData;
import cn.hutool.core.collection.CollectionUtil;
@Component
public class IndexDataClientFeignHystrix implements IndexDataClient {
	@Override
	public List<IndexData> getIndexData(String code) {
		IndexData indexData = new IndexData();
		indexData.setClosePoint(0);
		indexData.setDate("0000-00-00");
		return CollectionUtil.toList(indexData);
	}
}
 
								
										
									
								
							
					这就是用于提供所有模拟回测数据的微服务了。 当然,现在比较简单,随着业务的增加和功能的迭代,就会越来愈丰富起来了。 
					
				站长用这种由浅入深的方式来把这个复杂的服务逐渐发展起来,大家通过这个过程参与进来会更加容易理解和消化。 package cn.how2j.trend.service;
import cn.how2j.trend.client.IndexDataClient;
import cn.how2j.trend.pojo.IndexData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
@Service
public class BackTestService {
	@Autowired IndexDataClient indexDataClient;
	
	public List<IndexData> listIndexData(String code){
		List<IndexData> result = indexDataClient.getIndexData(code);
		Collections.reverse(result);
		
		for (IndexData indexData : result) {
			System.out.println(indexData.getDate());
		}
		
		return result;
	}
}
 
								
										
									
								
							
					控制器,返回的数据是放在一个 Map 里的,而目前的key是 indexDatas。 
					
				因为将来会返回各种各样的数据,通过这种方式才好区分不同的数据。 package cn.how2j.trend.web;
import cn.how2j.trend.pojo.IndexData;
import cn.how2j.trend.service.BackTestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
@RestController
public class BackTestController {
	@Autowired BackTestService backTestService;
	@GetMapping("/simulate/{code}")
	@CrossOrigin
	public Map<String,Object> backTest(@PathVariable("code") String code) throws Exception {
		List<IndexData> allIndexDatas = backTestService.listIndexData(code);
		Map<String,Object> result = new HashMap<>();
		result.put("indexDatas", allIndexDatas);
		return result;
	}
}
 
								
										
									
								
							
					启动类,注意一下: 
					
				@EnableFeignClients 这个注解用与启动 Feign 方式。 package cn.how2j.trend;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.NetUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import java.util.Scanner;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableFeignClients
public class TrendTradingBackTestServiceApplication {
    public static void main(String[] args) {
        int port = 0;
        int defaultPort = 8051;
        int eurekaServerPort = 8761;
        if(NetUtil.isUsableLocalPort(eurekaServerPort)) {
            System.err.printf("检查到端口%d 未启用,判断 eureka 服务器没有启动,本服务无法使用,故退出%n", eurekaServerPort );
            System.exit(1);
        }
        if(null!=args && 0!=args.length) {
            for (String arg : args) {
                if(arg.startsWith("port=")) {
                    String strPort= StrUtil.subAfter(arg, "port=", true);
                    if(NumberUtil.isNumber(strPort)) {
                        port = Convert.toInt(strPort);
                    }
                }
            }
        }
        if(0==port) {
            Future<Integer> future = ThreadUtil.execAsync(() ->{
                int p = 0;
                System.out.printf("请于5秒钟内输入端口号, 推荐  %d ,超过5秒将默认使用 %d ",defaultPort,defaultPort);
                Scanner scanner = new Scanner(System.in);
                while(true) {
                    String strPort = scanner.nextLine();
                    if(!NumberUtil.isInteger(strPort)) {
                        System.err.println("只能是数字");
                        continue;
                    }
                    else {
                        p = Convert.toInt(strPort);
                        scanner.close();
                        break;
                    }
                }
                return p;
            });
            try{
                port=future.get(5,TimeUnit.SECONDS);
            }
            catch (InterruptedException | ExecutionException | TimeoutException e){
                port = defaultPort;
            }
        }
        if(!NetUtil.isUsableLocalPort(port)) {
            System.err.printf("端口%d被占用了,无法启动%n", port );
            System.exit(1);
        }
        new SpringApplicationBuilder(TrendTradingBackTestServiceApplication.class).properties("server.port=" + port).run(args);
    }
}
 
								
										
									
								
							
					先启动 EurekaServerApplication 
					
				然后启动 IndexDataApplication 最后启动 TrendTradingBackTestServiceApplication 访问地址: http://127.0.0.1:8051/simulate/000300 
				HOW2J公众号,关注后实时获知最新的教程和优惠活动,谢谢。
			 
			 
			
			
			
			
			
		
			
			提问之前请登陆
			
		 
		提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢	
	 
 |