一个最简单的微服务架构

前言

微服务架构一般会有一个开放网关作为总入口,负责分发流量到实际的应用服务上。下面看图。

架构图

项目结构

这个架构分别由反向代理nginx,注册中心zookeeper,开放网关gateway,和两个服务goodservice,priceservice组件而成。为了方便测试,我把建了两个一样的gateway和goodservice。而common作为公共的二方包存在,也是为了简单起见,gateway和service引用同一个二方包。

nginx

nginx除了作为反向代理,也具有负载均衡的功能,默认策略是轮询地址列表。我这里设置8080和8081两个端口,如下

  upstream mygateway {
          server   localhost:8080;
          server   localhost:8081;
        }

    server {
        listen       80;
        server_name  localhost;

        location /route{
           proxy_pass http://mygateway;
        }
    }

priceservice

非常简单的服务,只提供一个价格查询的接口,如

@Service
public class PriceServiceImpl implements PriceService {
    @Override
    public Integer getGoodPrice(String name) {
        return 100;
    }
}

goodservice

也只提供一个接口,但是依赖priceservice,如

@Service
public class GoodServiceImpl implements GoodService {

    private final String SERVICENAME="goodservice";

    @Reference(check=false)
    PriceService priceService;

    @Override
    public List<GoodInfo> getGoodList(String name) {
        List<GoodInfo>  goodInfoList=new ArrayList<>();
        GoodInfo goodInfo=new GoodInfo();
        goodInfo.setName(name);
        goodInfo.setDescription(SERVICENAME);

        Integer price=  priceService.getGoodPrice(name);
        goodInfo.setPrice(price);

        goodInfoList.add(goodInfo);
        return goodInfoList;
    }
}

gateway

gateway这里的作用是提供一个统一对外的接口,当然还可以加上鉴权,限流,防黑,监控等功能。实现上是通过dubbo的泛化调用将流量通过负载均衡策略转到实际的应用中,均衡策略默认是随机。dubbo的泛化调用是需要去匹配对应接口的方法名和参数类型。正常情况下,是需要通过api注册和管理录入到数据库,再提供给gateway使用的。我这里通过静态块构造一些数据充当api注册。如下

@RestController
public class RouteController {
    private final static List<ServiceModel> serviceModels = new ArrayList<>();
    private final static Map<String,GenericService>  genericServiceMap=new HashMap<>();
    private final static String GATEWAYNAME="gateway";

    static {
        ParameterModel parameterModel = new ParameterModel();
        parameterModel.setName("name");
        parameterModel.setType("java.lang.String");
        List<ParameterModel> parameterModelList = new ArrayList<>();
        parameterModelList.add(parameterModel);

        ServiceModel serviceModel = new ServiceModel();
        serviceModel.setApiName("api.service.goodservice");
        serviceModel.setServiceName("com.example.demo.common.service.GoodService");
        serviceModel.setMethodName("getGoodList");

        serviceModel.setParameterModels(parameterModelList);
        serviceModels.add(serviceModel);
    }

    @RequestMapping(value = "/route", method = RequestMethod.GET)
    public ResultModel execute(@RequestParam String api, @RequestParam String data) {

        Optional<ServiceModel> serviceModelOptional = serviceModels.stream().filter(x -> x.getApiName().equals(api)).findFirst();
        ResultModel resultModel=new ResultModel();

        if (!serviceModelOptional.isPresent()) {
            resultModel.setDescription("api不存在");
        }
        ServiceModel serviceModel=serviceModelOptional.get();

        GenericService genericService= genericServiceMap.get(api);
        if(genericService==null){
            ReferenceConfig<GenericService> reference = new ReferenceConfig<>();
            reference.setInterface(serviceModel.getServiceName());
            reference.setGeneric(true);
            genericService = reference.get();
            genericServiceMap.put(api,genericService);
        }
        Object result = genericService.$invoke(serviceModel.getMethodName(),getTypeList(serviceModel).toArray(new String[]{}), dataToValueList(serviceModel,data).toArray());

        resultModel.setData(result);
        resultModel.setDescription(GATEWAYNAME);
        return resultModel;
    }

    /**
     * 获取参数类型列表
     * @param serviceModel
     * @return
     */
    private List<String> getTypeList(ServiceModel serviceModel) {
        List<ParameterModel> parameterModelList = serviceModel.getParameterModels();
        if (CollectionUtils.isEmpty(parameterModelList)) {
            return null;
        }
        return parameterModelList.stream().map(x -> x.getType()).collect(Collectors.toList());
    }

    /**
     * 获取data中的值列表
     * @param serviceModel
     * @param data
     * @return
     */
    private List<Object> dataToValueList(ServiceModel serviceModel, String data) {
        Map<String, Object> parameterMap = jsonToMap(data);
        List<ParameterModel> parameterModelList = serviceModel.getParameterModels();

        if (CollectionUtils.isEmpty(parameterModelList)) {
            return null;
        }
        List<Object> valueList = new ArrayList<>();

        parameterModelList.stream().forEach(x -> {
            valueList.add(parameterMap.get(x.getName()));
        });
        return valueList;
    }

    /**
     * 将map格式的string转成map对象
     * @param json
     * @return
     */
    public static Map<String, Object> jsonToMap(String json) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.readValue(json, Map.class);
        } catch (IOException e) {
            System.out.println(e);
        }
        return null;
    }
}

测试

接下来,方便起见,只需要在一台电脑把几个module全部启动起来,在浏览器输入

http://mygateway/route?api=api.service.goodservice&data={"name":"苹果"}

多测试几遍,会看到返回如下

{"data":[{"price":100,"name":"苹果","description":"goodservice","class":"com.example.demo.common.model.GoodInfo"}],"description":"gateway1"}
{"data":[{"price":100,"name":"苹果","description":"goodservice1","class":"com.example.demo.common.model.GoodInfo"}],"description":"gateway"}
{"data":[{"price":100,"name":"苹果","description":"goodservice","class":"com.example.demo.common.model.GoodInfo"}],"description":"gateway"}
{"data":[{"price":100,"name":"苹果","description":"goodservice1","class":"com.example.demo.common.model.GoodInfo"}],"description":"gateway1"}

实际上整个调用链路会在gateway集群和goodservice集群交叉流转,如果这个时候把goodservice或者gateway停掉,浏览器的调用还是会正常返回的,这就是集群的好处。

但是如果这个时候把停掉nginx,zookeeper和priceservice其中一个,浏览器将会调用失败,因为是单点的。在生产环境中,要保证高可用,架构上是不可以出现单点的应用。

小结

上面的架构只是微服务架构中的一种形态。阿里内部在这方面做得更极致一点,直接将gateway这层去掉,而是作为一个二方包集成到业务应用中,由接入层直接转发流量。简单来说,就是这样的。终端->LVS集群->Aserver集群(nginx的加强版)->应用服务。

git地址:  https://github.com/mycaizilin/microservice

原文地址:https://www.cnblogs.com/caizl/p/10797871.html

时间: 2024-10-04 18:24:33

一个最简单的微服务架构的相关文章

利用SpringCloud搭建一个最简单的微服务框架

http://blog.csdn.net/caicongyang/article/details/52974406 1.微服务 微服务主要包含服务注册,服务发现,服务路由,服务配置,服务熔断,服务降级等一系列的服务,而Spring Cloud为我们提供了个一整套的服务: 本例子为你提供了最简单的一个服务发现例子,包含服务注册发现spingCloudEurekaServer.服务配置中心spingCloudConfServer.以及一个app应用springCloudApp 2.服务注册与发现 s

面向服务与微服务架构

背景 最近阅读了 Martin Fowler 和 James Lewis 合著的一篇文章 Microservices, 文中主要描述和探讨了最近流行起来的一种服务架构模式--微服务,和我最近几年工作的实践比较相关感觉深受启发.本文吸收了部分原文观点,结合自身实践经验来探讨下服务架构模式的演化. 面向服务架构(SOA) 面向服务架构 SOA 思想概念的提出已不是什么新鲜事,大概在10年前就有不少相关书籍介绍过.当时 java 企业应用领域 J2EE 依然是主流,应用程序被部署在庞大统一的符合 J2

细说微服务架构的优势与不足那点事

摘要: 一个微服务一般完成某个特定的功能,比如下单管理.客户管理等等.每一个微服务都是微型六角形应用,都有自己的业务逻辑和适配器.一些微服务还 会发布API给其它微服务和应用客户端使用.其它微服务完成一个Web UI,运行时,每一个实例可能是一个云VM或者是Docker容器. 微服务正在博客.社交媒体讨论组和会议演讲中获得越来越多的关注,在Gartner的2014 Hype Cycle上它的排名非常靠前.同时,软件社区中也有不少持怀疑论者,认为微服务不是什么新东西.Naysayers认为这就是S

Re:从0开始的微服务架构--(二)快速快速体验微服务架构?--转

原文地址:https://mp.weixin.qq.com/s/QO1QDQWnjHZp8EvGDrxZvw 这是专题的第二篇文章,看看如何搭建一个简单模式的微服务架构. 记得好久之前看到一个大牛说过:如果单体架构都搞不好,就别搞微服务架构.乍一看,这句很有道理,后来发现这句话是不太对的,因为微服务架构的目的就是为了降低系统的复杂性,所以 微服务架构应该比单体架构更简单.更好实践才对. 这篇文章,我们就分享一下如何搭建一个 简单模式 的微服务架构. 什么是微服务架构的简单模式? 相对于大型互联网

Re:从0开始的微服务架构:(一)重识微服务架构--转

原文地址:http://www.infoq.com/cn/articles/micro-service-architecture-from-zero?utm_source=infoq&utm_medium=popular_widget&utm_campaign=popular_content_list&utm_content=homepage 导语 虽然已经红了很久,但是“微服务架构”正变得越来越重要,也将继续火下去. 各个公司与技术人员都在分享微服务架构的相关知识与实践经验,但我

微服务架构的优势与不足

<span "="">微服务正在博客.社交媒体讨论组和会议演讲中获得越来越多的关注,在Gartner的2014 Hype Cycle上它的排名非常靠前.同时,软件社区中也有不少持怀疑论者,认为微服务不是什么新东西.Naysayers认为这就是SOA架构的重新包装.然 而,尽管存在着不同的争论,微服务架构模式却正在为敏捷部署以及复杂企业应用实施提供巨大的帮助. <span "="">首先我们看看为什么要使用微服务. <

什么是微服务架构?

微服务(Microservices Architecture)是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成.系统中的各个微服务可被独立部署,各个微服务之间是松耦合的.每个微服务仅关注于完成一件任务并很好地完成该任务.在所有情况下,每个任务代表着一个小的业务能力. 单体架构(Monolithic Architecture ) 企业级的应用一般都会面临各种各样的业务需求,而常见的方式是把大量功能堆积到同一个单体架构中去.比如:常见的ERP.CRM等系统都以单体架构的方式运行,同时由于提

从0开始的微服务架构:(一)重识微服务架构

导语 虽然已经红了很久,但是"微服务架构"正变得越来越重要,也将继续火下去. 各个公司与技术人员都在分享微服务架构的相关知识与实践经验,但我们发现,目前网上的这些相关文章中,要么上来就是很有借鉴意义的干货,要么就是以高端的专业术语来讲述何为微服务架构.就是没有一个做到成熟地将技术传播出来,同时完美地照顾"初入微服务领域人员",从0开始,采用通俗易懂的语言去讲解微服务架构的系列. 所以,我们邀请青柳云的苏槐与InfoQ一起共建微服务架构专题"Re:从0开始的

你所不了解的微服务架构

一直以来,系统的架构设计是IT领域经久不衰的话题,也是构建每一个系统最核心且重要的部分之一.它决定了系统能否满足业务.技术.组织.灵活.可扩展性等多种要求,同时肩负起了解放程序员生产力的作用. 2016年底,由于业务的不断发展,我所在公司维护的项目也越来越"臃肿".随着无数个版本的迭代,以及开发人员的不断增加,开发效率越来越低,每次投产的人力成本和时间成本都逐渐增加,我们一直在思索如何能破局.评估了各种方案后,最终微服务进入了我们的视野. 谈到微服务,大家众说纷纭,但却很难有一个清晰的