一、背景

    我们现在有个项目是传统的spring mvc项目,由于业务一直在升级,代码也一直在随之变动修改,已经很庞大了;

    同志们也知道,目前微服务如日中天,跑到哪里不说下微服务都对不起自己,客户也是张口闭口微服务:“看看别人提供的方案,架构这么先进,你们太落后了。。”,面对着内忧外患,领导发话了,我们也要上微服务。

    上微服务现在的最佳方案都是使用spring cloud全家桶,不过我们现在的项目从架构到jar包都不支持,这也是老系统的通病,谁叫立项的时候cloud还没有出生呢。

    因此我们打算执行一个折中方案,老系统维持不变,新上的功能全部走spring boot,部署为独立的微服务,入口还是老项目,然后由老项目通过feign来访问新的微服务,这样的话新老系统都能完美运行。如果以后一定要全部升级为spring cloud的话,第一个是已经有了开发经验,第二个新的模块基本不需要变动,只需要把老项目进行更新即可,最大限度的保护研发成果。

 

二、架构图示

1.老项目示意图

 

2.新架构示意图

 

 

三、模块

1.common-vo

这里存放公共model,供其他服务调用

我们增加一个注解,用来模拟cloud里面的 FeignClient

这个注解待会儿是用来注册到spring容器中的

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyFeignClient {

    /**
     * 服务名--这个是保留项,准备用于eureka使用,根据name获取对应的url
     * @return
     */
    String name();

    /**
     * 指定url
     * @return
     */
    String url();

}

2.test-service-api

这里是调用微服务的接口api,客户端都是调用此接口

@MyFeignClient(name = "test-service", url = "localhost:9001")
public interface HelloRemoteService {
    @RequestLine("GET /hello?name={name}")
    String hello(@Param(value = "name") String name);

}

pom.xml

        <dependency>
			<groupId>io.github.openfeign</groupId>
			<artifactId>feign-core</artifactId>
			<version>9.7.0</version>
		</dependency>

		<dependency>
			<groupId>io.github.openfeign</groupId>
			<artifactId>feign-gson</artifactId>
			<version>9.7.0</version>
		</dependency>
		<dependency>
			<groupId>com.xxxx</groupId>
			<artifactId>common-vo</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>

需要注意的是api里面要依赖common-vo的项目

 

3.test-service

就是一个简单的controller,返回固定字符串即可

@RestController
public class HelloController {
    @RequestMapping("hello")
    public String index() {
        return "--hello  ,this is first messge";
    }
}

pom.xml就是普通的spring boot,这里就不发了

4.客户端访问

4.1普通访问

HelloRemoteService service = Feign.builder().options(new Request.Options(1000, 3500))
                    .retryer(new Retryer.Default(5000, 5000, 3))
                    .target(HelloRemoteService.class, "http://localhost:9001");
String ret = service.hello("scott");
logger.info("{}", ret);

这里的url是固定写入的,而且每个feign都这么使用的话,估计大家都会疯掉了。

4.2spring bean注册

为了解决4.1的问题,我们可以使用spring来扫描注册所有注解为MyFeignClient的bean,将所有的api都注册到spring 容器中

参考文档:https://my.oschina.net/yyqz/blog/1820970?from=timeline&isappinstalled=0

代码太长,这里就不贴出来了

在spring管理到所有注解为  MyFeignClient的bean后,我们就可以按以下方式执行了

 private final Logger       logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private HelloRemoteService helloRemoteService;

    @RequestMapping(name = "测试", value = "testHello")
    @ResponseBody
    public String service(HttpServletRequest request,
                          HttpServletResponse response) throws IOException {
        logger.info("第一个测试接口");
        String ret = helloRemoteService.hello("8888");
        return ret;
    }

做完这么多后,我们已经达到第一个目标,老项目使用feign来访问新建的微服务,当然这里还缺少eureka服务发现,服务熔断降级、负载均衡等等cloud的集成功能,这个我们以后再来根据实际情况考虑吧。

 

 

    

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐