为您推荐:
精华内容
最热下载
问答
  • 5星
    69.48MB qq_17556735 2021-03-13 22:42:11
  • 项目中引入了Dubbo,对外需要提供一个Dubbo的接口服务,编写了一个demo,在此提供出来,供初学引用。  主要包括:在spring项目中引入对dubbo的支持,编写dubbo的provider和consumer,提供一个可测试的小demo。 ...

    原文路径:http://blog.csdn.net/xinluqishi123/article/details/64124503

    项目中引入了Dubbo,对外需要提供一个Dubbo的接口服务,编写了一个demo,在此提供出来,供初学者引用。 

    主要包括:在spring项目中引入对dubbo的支持,编写dubbo的provider和consumer,提供一个可测试的小demo。

    目标:开发环境中添加对Dubbo的支持,编写Dubbo服务的提供者和消费者。

    环境:Spring4.0, Dubbo2.5.3, Zookeeper3.4.6,maven3.3.9

    步骤:

    1. 独立建立一个java maven项目,将所有的dubbo服务接口,这里只是接口以及包含的接口方法放置其中。 
      类似如下的结构: 
      这里写图片描述
      app包下放置的就是你自己定义的dubbo接口和接口方法,这里我写的一个接口如下:
    package yourpackage.app;
    
    /**
     * 对外提供发送短信的Dubbo服务
     * @author kevin shi
     *
     */
    
    public interface ISendMessageService {
    
        void sendMessage(int serialNo, String destAddr_cmcc, String messageContent);
    
    }
    
    

    我这里写了一个发送短息的dubbo服务,可以调用这个接口发送短信,可以把短信内容,发送目标等等作为参数传递进来。单独建立一个项目存放接口是为了开发provider和consumer的时候可以方便以jar包的形式调用,因为你的provider或者consumer也许是在单独的项目中,而且也可能是不同的人编写。 
    你可以将这个项目导出jar包,并上传到你的私服上供其他的项目开发者下载依赖引用。

    1. 编写Dubbo服务的provider: 
      首先,在项目中加入对Dubbo服务的依赖支持:
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>dubbo</artifactId>
                <version>2.5.3</version>
                <exclusions>
                    <exclusion>
                        <artifactId>spring</artifactId>
                        <groupId>org.springframework</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
    
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.4.6</version>
            </dependency>
    
            <dependency>
             <groupId>com.github.sgroschupf</groupId>
             <artifactId>zkclient</artifactId>
             <version>0.1</version>
            </dependency>
    
            <dependency>
              <groupId>yourpackage.common</groupId>
              <artifactId>dubbo-common</artifactId>
              <version>0.0.1-SNAPSHOT</version>
            </dependency>dubbo和spring融合的依赖引用,zookeeper和client都配置在这里了,client也许不需要,但是我都配置上了,最后一个是对步骤1中编写的dubbo-common项目的jar包依赖。
    其次,编写xml配置文件,可以叫做spring-dubbo-provider.xml,配置你的Dubbo服务的provider,因为有了接口你还需要写实现类实现这个接口服务提供给consumer:
    
    <!-- 注册dubbo服务的应用名称。 -->
    <dubbo:application name="dubbo_provider" />
    <!-- 此处配置zookeeper注册中心的服务地址 -->
    <dubbo:registry address="zookeeper://10.11.12.13:1001"  check="false"/>
    <!-- Dubbo服务提供者的服务地址和端口号 -->
    <dubbo:protocol host="127.0.0.1"  name="dubbo" port="20891"></dubbo:protocol>
    <!-- 此处配置服务提供者的接口实现类,yourpackage.ISendMessageService是Dubbo服务的接口路径,sendMessageService是引用的接口实现类bean的名称。 -->
    <dubbo:service interface="yourpackage.ISendMessageService" ref="sendMessageService" timeout="1200000" 
    最后,编写Dubbo服务提供者的接口实现类:
    
        package yourpackage.common.service.impl;
    
        import org.springframework.stereotype.Service;
    
        import yourpackage.ISendMessageService;
        import yourpackage.common.utils.SMSUtil;
    
        @Service("sendMessageService")
        public class SendMessageServiceImpl implements ISendMessageService{
    
            @Override
            public void sendMessage(int serialNo, String destAddr_cmcc, String messageContent) {
                SMSUtil.send(serialNo, destAddr_cmcc, messageContent);
            }
        }编写Dubbo服务consumer 
    1. 首先,编写xml配置文件,可以叫做spring-dubbo-consumer.xml,(pom文件中依赖的引用参考provider的配置), 
      消费端应该与服务提供端处于不同的项目中,在一个项目中只能提供一个,否则会报错,但是可以配置多个接口。
        <dubbo:application name="dubbo_consumer" />
        <dubbo:registry  protocol="zookeeper"  address="zookeeper://10.11.12.13:1001" />
        <dubbo:reference interface="yourpackage.ISendMessageService" id="sendMessageServiceConsumer" url="dubbo://127.0.0.1:20891" timeout="1200000" />消费端的应用名称应该与服务提供端的应用名称不同,这里是“dubbo_consumer”; 

    注册的zookeeper地址名称与服务提供端相同; 
    标签配置的是dubbo服务接口名称;声明这个接口对应的引用beanID是“sendMessageServiceConsumer”,在消费端调用这个接口时可以直接获取这个名字;url对应dubbo provider自己声明的服务地址,也就是对应标签的内容; 
    注意此处的timeout必须填写,否则会造成客户端连接很快过期而无法调用dubbo服务的情况。

    其次,编写consumer的调用代码(此处简单调用):

        package yourpackage.common.service;
    
        import org.springframework.context.support.ClassPathXmlApplicationContext;
    
        import yourpackage.ISendMessageService;
    
        public class SendMessageServiceConsumerImpl {
    
            public static void handleSendMessage() {
                ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "spring-dubbo-consumer.xml" });  
                context.start();  
                ISendMessageService sendService = (ISendMessageService) context.getBean("sendMessageServiceConsumer");  //这里对应配置文件中声明的beanId
                sendService.sendMessage(12345, "2222222", "3333333");
            }
    
            public static void main(String[] args) {
                SendMessageServiceConsumerImpl.handleSendMessage();
            }
        }ok,一切就绪,我们可以在借助tomcat启动Dubbo服务的provider后,运行consumer的main函数,即可调用到provider的接口实现类,从而可以进行后续功能扩展和测试。

    谢谢你能看到这里,如有错误请批评指正,也可以给我留言谈到其他问题。

    展开全文
    luoxiang183 2017-11-10 11:04:35
  • 本篇博文中我们以一个dubbo服务api调用方式开篇,对于dubbo服务发布配置,解析、构造URL和发布服务整个流程的源码进行了分析。对于读者能更好的理解dubbo的服务发布过程,其中最核心的概念应该是Dubbo自己封装的...

    目录

    1、dubbo服务提供者api

    2、dubbo相关配置的描述

    3、服务发布

           3.1、export()

           3.2、doExport()方法

           3.3、doExportUrls()方法

    4、doExportUrlsFor1Protocol()

           4.1、构建DubboURL

           4.2、dubbo服务暴露


     前言:

           在之前的dubbo源码解析中,我们大致了解了spring+dubbo整合案例以及spring入口分析和dubbo配置相关解析,在此学习过程中了解了dubbo相关的AbstrcatConfig相关配置类,

    这些类是我们使用dubbo的最基础的配置类,因为具体的dubbo功能实现还是其对应的api在起作用,使用spring我们只是使用了其核心的容器IOC来便于我们业务开发,下面我们抛开spring来单独研究dubbo的api调用过程,有关api的调用笔者准备使用两篇博客进行介绍分别为服务提供和服务消费。

    1、dubbo服务提供者api

       /**
         * 使用api编码的形式进行dubbo服务暴露
         */
        public void exportService(){
            //模拟spring服务实现(此处不使用spring环境 读者可以自行使用)
            UserService demoService = new UserServiceImpl();
    
            //1、创建应用信息(服务提供者和服务消费者均需要,以便用于计算应用之间的依赖关系)
            ApplicationConfig appliction = new ApplicationConfig("demo-core");
    
            //2、创建注册中心(服务提供者和服务消费者均需要,以便用于服务注册和服务发现)
            //dubbo支持的注册中心:①simple、②Multicast、③zookeeper、④ redis
            //这里采用zookeeper(常用也是dubbo推荐使用的)
            RegistryConfig registry = new RegistryConfig();
            registry.setAddress("zookeeper://182.92.189.235:2181");
    
            //3、创建服务暴露后对应的协议信息,该设置约定了消费者使用哪种协议来请求服务提供者
            //dubbo消费协议如下:   ①dubbo://、②hessian://、③rmi://、 ④http://、⑤webservice://、⑦memcached://、⑧redis://
            ProtocolConfig protocol = new ProtocolConfig();
            //使用dubbo协议
            protocol.setName("dubbo");
            protocol.setPort(28830);
    
            //4、该类为服务消费者的全局配置(比如是否延迟暴露,是否暴露服务等)
            ProviderConfig provider = new ProviderConfig();
            //是否暴露服务
            provider.setExport(true);
            //延迟一秒发布服务
            provider.setDelay(1000);
    
            //5、服务提供者 会配置应用、注册、协议、提供者等信息
            ServiceConfig<UserService> serviceService = new ServiceConfig<>();
            //设置应用信息
            serviceService.setApplication(appliction);
            //设置注册信息
            serviceService.setRegistry(registry);
            //设置相关协议
            serviceService.setProtocol(protocol);
            //设置全局配置信息
            serviceService.setProvider(provider);
            //设置接口信息
            serviceService.setInterface(UserService.class);
            serviceService.setRef(demoService);
            
            //6、服务发布 (最终上面设置的相关信息转换为Dubbo URL的形式暴露出去)
            serviceService.export();
            while (true){
            }
        }

    在上述代码中我们核心关注的ServiceConfig(dubbo服务的提供),但是我们也不能忽视为使ServiceConfig的功能能够使用的其他配置列如:注册(RegistryConfig)、协议(ProtocolConfig)、服务提供者全局配置(ProviderConfig)等。

    2、dubbo相关配置的描述

    下面贴出其配置的UML类图




      1、AbstractConfig 主要提供配置解析与校验相关的通用方法
         比如配置解析
           appendParameters()方法:根据类上所有公有方法的@Parameter注解从配置信息获取配置并通过setXXX方法填充
           appendAttributes()方法:根据类上所有公有方法的@Parameter注解从配置信息获取配置存放到map集合中
        比如校验
           checkExtension()方法:检查属性的长度和非法字符串

      2、ModubleConfig  模块信息

           我们可以针对一个应用区分不同模块,并为模块设置不同的配置信息 比如注册信息,协议信息等

      3、ProviderConfig   服务提供者全局配置

      4、RegistryConfig 注册相关配置,dubbo目前支持的注册中心有五种分别为:

             (1)、Zookeeper (2)、Multicast (3)、Redis (4)、Simple

      5、MonitorConfig 监控中心配置

      6、ProtocolConfig dubbo服务请求协议

             dubbo消费协议如下:  ①dubbo://、②hessian://、③rmi://、 ④http://、⑤webservice://、⑦memcached://、⑧redis://

      7、ProviderConfig   服务提供者全局配置

      8、dubbo的URL
        dubbo上面的所有配置对象都将被转换为 com.alibaba.dubbo.common.URL,Dubbo中无论是服务消费方、服务提供方、注册中心都是通过URL进行定位资源。

    1、dubbo://xxx.xx.xx.x:xxxx/moe.cnkirito.sample.HelloService?timeout=3000
    描述一个 dubbo 协议的服务
    
    2、zookeeper://1xxx.xx.xx.x:xxxx/org.apache.dubbo.registry.RegistryService?application=demo-consumer&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=1214&qos.port=33333&timestamp=1545721981946
    描述一个 zookeeper 注册中心
    
    3、consumer://xxx.xx.xx.x:xxxx/org.apache.dubbo.demo.DemoService?application=demo-consumer&category=consumers&check=false&dubbo=2.0.2&interface=org.apache.dubbo.demo.DemoService&methods=sayHello&pid=1209&qos.port=33333&side=consumer&timestamp=1545721827784
    描述一个消费者

    ServiceConfig.export() 或 ReferenceConfig.get()初始化时,将 Bean 对象转换 URL 格式,所有 Bean 属性转成 URL 的参数。

    上面我们针对api发布服务的相关配置进行了介绍,在编码中除了进行配置实例化和设置后,最终调用export()进行了发布使服务暴露出去从而能被消费者消费,下面我们来看一看export的相关逻辑实现。

    3、服务发布

         3.1、export()

    //服务发布入口    
    public synchronized void export() {
        //从其全局服务提供者ProviderConfig中获取发布相关配置
        //export(boolean) 是否需要对外暴露 不对外暴露则返回
        //delay(毫秒) 延迟对外暴露的时间
        if (provider != null) {
            if (export == null) {
                export = provider.getExport();
            }
            if (delay == null) {
                delay = provider.getDelay();
            }
        }
        if (export != null && !export) {
            return;
        }
        //此处不管延迟发布还是即时发布均调用doExport()方法
        if (delay != null && delay > 0) {
            delayExportExecutor.schedule(new Runnable() {
                @Override
                public void run() {
                    doExport();
                }
            }, delay, TimeUnit.MILLISECONDS);
        } else {
            doExport();
        }
    }

       该方法逻辑比较简单 主要获取发布相关配置 1、export(boolean) 是否需要对外暴露 不对外暴露则返回2、delay(毫秒) 延迟对外暴露的时间,通过doExport()方法来实现真正的服务部署。

     3.2、doExport()方法

    protected synchronized void doExport() {
        //1、发布相关参数校验 比如重复部署、服务接口名为空等
        省略相关代码.....
        //2、校验全局默认配置ProviderConfig存在与否(不存在新建一个)
        //并获取应用信息、模块信息、注册信息、监控信息等
        checkDefault();
        //应用、模块信息不存在可以从ProviderConfig获取
        //获取注册,监控相关信息的优先级 ProviderConfig(全局服务提供者)>ModuleConfig(模块信息)>Application(应用信息)
        省略相关代码.....
        //3、获取服务接口Class属性
        //dubbo服务提供和消费支持两种类型的接口一种是具体的接口和实现 另一种是泛化接口
        //所谓泛化接口是指我们可以使用GenericService来调用任何已经存在的类的方法而不依赖于具体接口方法
        //java应用内部接口都是使用dubbo,某个非java应用需要调用我们的接口的时候,无法使用dubbo,
        // 这是我们需要给它提供其他形式的接口,如restful api等等,这时我们需要为这个接口开发而增加额外的工作量。
        // 这时候就可以使用dubbo提供的GenericService来调用dubbo接口了,
        // 而使用GenericService调用接口的好处是不需要依赖服务提供方给的interface,
        // 只需要知道接口的全类名,方法名,参数列表就能调用dubbo方法,拿到返回值,这种调用称为泛化调用
    
        //获取接口Class 如果是泛化接口加上泛化标识 具体接口方法需要坚持ref对应的服务实现类
        if (ref instanceof GenericService) {
            interfaceClass = GenericService.class;
            if (StringUtils.isEmpty(generic)) {
                generic = Boolean.TRUE.toString();
            }
        } else {
            try {
                interfaceClass = Class.forName(interfaceName, true, Thread.currentThread()
                        .getContextClassLoader());
            } catch (ClassNotFoundException e) {
                throw new IllegalStateException(e.getMessage(), e);
            }
            checkInterfaceAndMethods(interfaceClass, methods);
            checkRef();
            generic = Boolean.FALSE.toString();
        }
        //4、本地调用当一个应用既是一个服务的提供者,同时也是这个服务的消费者的时候,可以直接对本机提供的服务发起本地调用
        //该功能已经废弃,因为如果我要使用内部服务直接api调用即可,为何需要多此一举进行调用自己内部服务
        //底层是默认使用 injvm 的协议暴露本地服务,scope="remote" 来关闭 injvm 协议的暴露 使得dubbo内外服务统一使用相同协议
        if (local != null) {
            if ("true".equals(local)) {
                local = interfaceName + "Local";
            }
            Class<?> localClass;
            try {
                localClass = ClassHelper.forNameWithThreadContextClassLoader(local);
            } catch (ClassNotFoundException e) {
                throw new IllegalStateException(e.getMessage(), e);
            }
            if (!interfaceClass.isAssignableFrom(localClass)) {
                throw new IllegalStateException("The local implementation class " + localClass.getName() + " not implement interface " + interfaceName);
            }
        }
        //5、dubbo的本地存根的原理是:远程服务后,客户端通常只剩下接口,而实现全在服务器端,
        //但提供方有些时候想在客户端也执行部分逻辑,那么就在服务消费者这一端提供了一个Stub类,
        //然后当消费者调用provider方提供的dubbo服务时,客户端生成 Proxy 实例,这个Proxy实例就是我们正常调用dubbo远程服务要生成的代理实例,
        //然后消费者这方会把 Proxy 通过构造函数传给 消费者方的Stub ,然后把 Stub 暴露给用户,Stub 可以决定要不要去调 Proxy。
        //会通过代理类去完成这个调用,这样在Stub类中,就可以做一些额外的事,来对服务的调用过程进行优化或者容错的处理
        if (stub != null) {
            if ("true".equals(stub)) {
                stub = interfaceName + "Stub";
            }
            Class<?> stubClass;
            try {
                stubClass = ClassHelper.forNameWithThreadContextClassLoader(stub);
            } catch (ClassNotFoundException e) {
                throw new IllegalStateException(e.getMessage(), e);
            }
            if (!interfaceClass.isAssignableFrom(stubClass)) {
                throw new IllegalStateException("The stub implementation class " + stubClass.getName() + " not implement interface " + interfaceName);
            }
        }
        //6、如果在服务类中配置mock属性 在调用真实的接口不通,就会调用你的mock类
        //(mock类和真实实现类都Implements 同一个接口,自己mock的名字要是:接口类名+mock)
        
        //7、检查并填充相关dubbo配置
        //检查并填充Application 应用
        checkApplication();
        //检查并填充Registry 注册中心
        checkRegistry();
        //检查并填充Protocol 协议信息
        checkProtocol();
        //填充服务提供者相关信息
        appendProperties(this);
        //添加mock、local、stub相关配置class
        checkStubAndMock(interfaceClass);
        if (path == null || path.length() == 0) {
            path = interfaceName;
        }
        //8、生成Dubbo URL并发布
        doExportUrls();
        //9、将对应的服务提供者包装成ProviderModel存放到集合中
        ProviderModel providerModel = new ProviderModel(getUniqueServiceName(), this, ref);
        ApplicationModel.initProviderModel(getUniqueServiceName(), providerModel);
    }

    该方法主要流程如下:

    1、发布相关参数校验 比如重复部署、服务接口名为空等
    
    2、校验全局默认配置ProviderConfig存在与否(不存在新建一个)
    并获取应用信息、模块信息、注册信息、监控信息等
    
    3、获取服务接口Class属性 其中涉及泛化接口和具体接口
       //dubbo服务提供和消费支持两种类型的接口一种是具体的接口和实现 另一种是泛化接口
      //所谓泛化接口是指我们可以使用GenericService来调用任何已经存在的类的方法而不依赖于具体接口方法
      //java应用内部接口都是使用dubbo,某个非java应用需要调用我们的接口的时候,无法使用dubbo,
      // 这是我们需要给它提供其他形式的接口,如restful api等等,这时我们需要为这个接口开发而增加额外的工作量。
      // 这时候就可以使用dubbo提供的GenericService来调用dubbo接口了,
      // 而使用GenericService调用接口的好处是不需要依赖服务提供方给的interface,
      // 只需要知道接口的全类名,方法名,参数列表就能调用dubbo方法,拿到返回值,这种调用称为泛化调用
    4、dubbo的local(本地调用)、stub(存根)、mock(异常降级)相关class属性
    
    5、检查并填充相关dubbo配置,比如应用信息、注册信息。协议信息、服务提供者信息
    
    6、生成Dubbo URL并发布
    
    7、服务提供者包装成ProviderModel存放到集合

     3.3、doExportUrls()方法

     private void doExportUrls() {
            //根据当前服务提供者的属性信息(主要是注册中心配置信息) 解析生成对应的注册中心相关的Dubbo URL
            //dubbo支持多个注册中心所以返回集合
            //registry://xxx/com.alibaba.dubbo.registry.RegistryService?application=demo-core&dubbo=2.6.2
            // &pid=71868&registry=zookeeper&timestamp=1621744928203
            List<URL> registryURLs = loadRegistries(true);
            //同理dubbo也支持服务多协议 所以此处需要针对每一种协议发布服务到所有的注册中心
            for (ProtocolConfig protocolConfig : protocols) {
                //具体进行Dubbo URL创建和服务暴露的逻辑
                doExportUrlsFor1Protocol(protocolConfig, registryURLs);
            }
        }

      上述方法 仅仅针对多个注册中心,多种协议生成对应的Dubbo URL并进行服务暴露,比如有两个注册中心,两种dubbo协议则会生成4种不同的Dubbo URL,最终调用doExportUrlsFor1Protocol()方法进行具体的DubboURL创建和部署操作,下面来分析doExportUrlsFor1Protocol()方法。

    4、doExportUrlsFor1Protocol()方法

           该方法代码量比较多,这里根据业务逻辑分成两个部分进行分别解读,虽然代码量很多但是还是很好理解。

    • dubbo相关配置解析并根据相关配置构建Dubbo URL
    • dubbo URL 构建的服务进行服务发布(暴露出来供消费者消费)

        4.1、构建DubboURL

        /**
         * 转换配置信息为Dubbo url
         * @param protocolConfig 协议配置信息类
         * @param registryURLs 注册中心(多个)
         */
        private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
            //从dubbo相关配置获取信息存放到map中 比如服务是提供者还是消费者 dubbo版本信息 pid以及等等
            //获取协议类型 dubbo:// 还是 http://等等
            String name = protocolConfig.getName();
            if (name == null || name.length() == 0) {
                name = "dubbo";
            }
    
            Map<String, String> map = new HashMap<String, String>();
            //服务类型 提供者还是消费者 provider、consumer
            map.put(Constants.SIDE_KEY, Constants.PROVIDER_SIDE);
            //dubbo version 版本
            map.put(Constants.DUBBO_VERSION_KEY, Version.getVersion());
            //时间戳
            map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
            if (ConfigUtils.getPid() > 0) {
                map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));
            }
            //map中添加从应用信息、模块信息、提供者信息、协议信息、服务信息获取的相关信息
            appendParameters(map, application);
            appendParameters(map, module);
            appendParameters(map, provider, Constants.DEFAULT_KEY);
            appendParameters(map, protocolConfig);
            appendParameters(map, this);
    
            //如果ServiceConfig和ReferenceConfig中配置了method属性则需要解析其中的MethodConfig属性添加到map中
            //配置了args属性则需要解析其中的ArgumentConfig属性添加到map中
            //MethodConfig和ArgumentConfig比较少用 此处生路不详述
            if (methods != null && !methods.isEmpty()) {
                //MethodConfig和ArgumentConfig解析其中属性存放map中
            }
            //map中添加泛化接口信息
            if (ProtocolUtils.isGeneric(generic)) {
                map.put(Constants.GENERIC_KEY, generic);
                map.put(Constants.METHODS_KEY, Constants.ANY_VALUE);
            } else {
             //具体的dubbo服务接口信息
             //map中添加dubbo修订版本信息
                String revision = Version.getVersion(interfaceClass, version);
                if (revision != null && revision.length() > 0) {
                    map.put("revision", revision);
                }
                //map中添加暴露的接口的所有方法对象属性
                String[] methods = Wrapper.getWrapper(interfaceClass).getMethodNames();
                if (methods.length == 0) {
                    logger.warn("NO method found in service interface " + interfaceClass.getName());
                    map.put(Constants.METHODS_KEY, Constants.ANY_VALUE);
                } else {
                    map.put(Constants.METHODS_KEY, StringUtils.join(new HashSet<String>(Arrays.asList(methods)), ","));
                }
            }
            //map中添加token属性
            if (!ConfigUtils.isEmpty(token)) {
                if (ConfigUtils.isDefault(token)) {
                    map.put(Constants.TOKEN_KEY, UUID.randomUUID().toString());
                } else {
                    map.put(Constants.TOKEN_KEY, token);
                }
            }
            if (Constants.LOCAL_PROTOCOL.equals(protocolConfig.getName())) {
                protocolConfig.setRegister(false);
                map.put("notify", "false");
            }
            //获取协议上下文路径(用于构造dubbo的URL)
            String contextPath = protocolConfig.getContextpath();
            if ((contextPath == null || contextPath.length() == 0) && provider != null) {
                contextPath = provider.getContextpath();
            }
            //服务实现所在的应用ip和port
            String host = this.findConfigedHosts(protocolConfig, registryURLs, map);
            Integer port = this.findConfigedPorts(protocolConfig, name, map);
            //构建Dubbo对应的url接口,参数大部分来自于map(之前所有解析dubbo相关属性都存在于map中)
            URL url = new URL(name, host, port, (contextPath == null || contextPath.length() == 0 ? "" : contextPath + "/") + path, map);
    
            //这里的ConfiguratorFactory是个扩展,可以用来设计自己的URL组成规则
            if (ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
                    .hasExtension(url.getProtocol())) {
                url = ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
                        .getExtension(url.getProtocol()).getConfigurator(url).configure(url);
            }
            //省略服务暴露的相关代码
            //......
    }

       构建dubbo URL代码比较繁琐,但是简单都是生成或者从ApplicationConfig(dubbo应用配置信息)、ModuleConfig(dubbo模块配置信息)等获取dubbo服务提供者相关配置信息,比如ip、host、接口类(interface),方法(methods)等信息,最终将这些配置信息构建成com.alibaba.dubbo.common.URL。

         dubbo URL补充

           Dubbo框架是以URL为总线的模式,即运行过程中所有的状态数据信息都可以通过URL来获取,比如当前系统采用什么序列化,采用什么通信,采用什么负载均衡等信息,都是通过URL的参数来呈现的。

         如上代码最终生成的服务URL如下:

    dubbo://192.168.1.16:28830/com.xiu.dubbo.service.UserService?anyhost=true&application=demo-core&bind.ip=192.168.1.16&bind.port=28830&default.delay=1000&default.export=true&delay=1000&dubbo=2.6.2&export=true&generic=false&interface=com.xiu.dubbo.service.UserService&methods=queryUserInfo&pid=53692&side=provider&timestamp=1621766013477

    属性配置属性说明

    dubbo://

    dubbo服务提供者使用的服务协议 有dubbo、http等
    192.168.1.16:28830/服务ip和端口
    com.xiu.dubbo.service.UserService服务名
    ?anyhost=true是否被所有ip消费者使用
    &application=demo-core应用名
    &bind.ip=192.168.1.16
    &bind.port=28830
    服务所在的服务器地址和发布的端口
    &default.delay=1000默认延迟暴露时间
    &delay=1000自定义设置的延迟暴露时间
    &dubbo=2.6.2dubbo版本
    &generic=false是否泛化接口
    &interface=com.xiu.dubbo.service.UserService接口类
    &methods=queryUserInfo接口方法列表
    &pid=53692pid
    &side=provider服务类型 提供者provider 消费者 Consumer
    &timestamp=1621766013477时间戳

       4.2、dubbo服务暴露

      private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
            //省略构造Dubbo URL方法
            //获取URL的dubbo服务的暴露范围 scope的配置决定是作本地暴露还是远程暴露
            String scope = url.getParameter(Constants.SCOPE_KEY);
            // 配置不为none则进行暴露
            if (!Constants.SCOPE_NONE.toString().equalsIgnoreCase(scope)) {
                //如何暴露范围没有配置 则即进行本地暴露也进行远程暴露
                配置不是remote的情况下做本地暴露 (配置为remote,则表示只暴露远程服务)
                if (!Constants.SCOPE_REMOTE.toString().equalsIgnoreCase(scope)) {
                    exportLocal(url);
                }
                //如果配置不是local则暴露为远程服务.(配置为local,则表示只暴露本地服务)
                if (!Constants.SCOPE_LOCAL.toString().equalsIgnoreCase(scope)) {
                    if (logger.isInfoEnabled()) {
                        logger.info("Export dubbo service " + interfaceClass.getName() + " to url " + url);
                    }
                    //远程暴露需要依赖注册中心 同时如果有监控中心也需要添加到dubbo URL上
                    //注册中心可能会在dubboURL上添加&dynamic=xxx 监控中心会在dubboURL上添加&monitor=xxx
                    if (registryURLs != null && !registryURLs.isEmpty()) {
                        for (URL registryURL : registryURLs) {
                            url = url.addParameterIfAbsent(Constants.DYNAMIC_KEY, registryURL.getParameter(Constants.DYNAMIC_KEY));
                            URL monitorUrl = loadMonitor(registryURL);
                            if (monitorUrl != null) {
                                url = url.addParameterAndEncoded(Constants.MONITOR_KEY, monitorUrl.toFullString());
                            }
                            if (logger.isInfoEnabled()) {
                                logger.info("Register dubbo service " + interfaceClass.getName() + " url " + url + " to registry " + registryURL);
                            }
                            //com.alibaba.dubbo.rpc.ProxyFactory 是dubbo rpc调用生成动态代理的核心
                            //在该服务提供者中 会将具体的实现类转换为com.alibaba.dubbo.rpc.Invoker ,
                            //而在服务消费者中,会通过getProxy(Invoker invoker)将invoker转为客户端需要的接口。
                            Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));
                            DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);
                            //发布服务
                            Exporter<?> exporter = protocol.export(wrapperInvoker);
                            exporters.add(exporter);
                        }
                    } else {
                        //没有注册中心时候的dubbo直连使用该处逻辑
                        Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url);
                        DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);
                        Exporter<?> exporter = protocol.export(wrapperInvoker);
                        exporters.add(exporter);
                    }
                }
            }
            this.urls.add(url);
        }

         如上代码进行服务暴露,主要有两种方式

    1. 本地暴露 exportLocal(URL)
    2. 远程暴露(通过注册中心暴露服务和dubbo直连)

     无论是本地暴露还是远程暴露都是使用com.alibaba.dubbo.rpc.ProxyFactory 是dubbo rpc调用生成动态代理的com.alibaba.dubbo.rpc.Invoker实例

      <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException; 该方法有三个参数 1、是接口实现类对象 2、接口class 3、Dubbo URL

    在该服务提供端中 会将具体的实现类转换为com.alibaba.dubbo.rpc.Invoker 
    而在服务消费端中,会通过getProxy(Invoker invoker)将invoker转为客户端需要的接口。
    展开全文
    liushangzaibeijing 2021-05-23 10:27:53
  • 服务提供方及服务消费方的配置示例 provider xml version="1.0" encoding="UTF-8"?> xmlns=...
    服务提供方及服务消费方的配置示例
    provider
       
    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    6. <!-- 提供方应用信息,用于计算依赖关系 -->
    7. <dubbo:application name="hello-world-app" />
    8. <!-- 使用multicast广播注册中心暴露服务地址 -->
    9. <dubbo:registry address="multicast://224.5.6.7:1234" check="false" subscribe="true" register=""/>
    10.     <dubbo:provider protocol="dubbo" accepts="10" timeout="50000" retries="0"></dubbo:provider>
    11. <!-- 用dubbo协议在20880端口暴露服务 -->
    12. <dubbo:protocol name="dubbo" port="20880" />
    13. <!-- 和本地bean一样实现服务 -->
    14. <bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl" />
    15. <!-- 声明需要暴露的服务接口 -->
    16. <dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService" />
    17. </beans>
    consumer
       
    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    6. <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
    7. <dubbo:application name="consumer-of-helloworld-app" />
    8. <!-- 使用multicast广播注册中心暴露发现服务地址 -->
    9. <dubbo:registry address="multicast://224.5.6.7:1234" check="false" subscribe="true" register=""/>
    10.     <!-- 声明服务调用超时时间 -->
    11.     <dubbo:consumer timeout="5000" ></dubbo:consumer>
    12. <!-- 生成远程服务代理,可以和本地bean一样使用demoService / retries重试次数配置 -->
    13. <dubbo:reference id="demoService" interface="com.alibaba.dubbo.demo.DemoService" retries="2"/>
    14. </beans>

    <dubbo:service/> 服务配置,用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心。
    <dubbo:reference/> 引用配置,用于创建一个远程服务代理,一个引用可以指向多个注册中心。
    <dubbo:protocol/> 协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。
    <dubbo:application/> 应用配置,用于配置当前应用信息,不管该应用是提供者还是消费者。
    <dubbo:module/> 模块配置,用于配置当前模块信息,可选。
    <dubbo:registry/> 注册中心配置,用于配置连接注册中心相关信息。
    <dubbo:monitor/> 监控中心配置,用于配置连接监控中心相关信息,可选。
    <dubbo:provider/> 提供方的缺省值,当ProtocolConfig和ServiceConfig某属性没有配置时,采用此缺省值,可选。
    <dubbo:consumer/> 消费方缺省配置,当ReferenceConfig某属性没有配置时,采用此缺省值,可选。
    <dubbo:method/> 方法配置,用于ServiceConfig和ReferenceConfig指定方法级的配置信息。
    <dubbo:argument/> 用于指定方法参数配置。

    参考地址:
    阿里巴巴分布式服务框架: http://www.iteye.com/magazines/103
    框架用户指南地址: http://dubbo.io/User+Guide-zh.htm#UserGuide-zh-%E8%83%8C%E6%99%AF


    展开全文
    mingdry0304 2017-05-17 09:18:41
  • Nacos安装与运行2.1、下载Nacos2.2、解压Nacos2.3、运行Nacos2.4、访问Nacos第三章 Nacos作注册中心3.1、服务提供者3.1.1、创建工程3.1.2、导入依赖3.1.3、编写配置3.1.4、主启动类3.1.5、控制器类3.1.6、启动测试...


    配套资料,免费下载
    链接:https://pan.baidu.com/s/1-eRFozbFIShqbqNRFD9KDw
    提取码:rt3w
    复制这段内容后打开百度网盘手机App,操作更方便哦

    第一章 Nacos的介绍

    1.1、Nacos是什么

    Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。

    Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

    简单来说,Nacos 就是Eureka + Spring Cloud Config + Spring Cloud Bus的增强版本,融合了众多技术于一身,更简单,更易用,更强大。

    官方文档:https://nacos.io/zh-cn/docs/what-is-nacos.html

    源码地址:https://github.com/alibaba/nacos

    1.2、Nacos的特性

    • 服务发现和服务健康监测

      Nacos 支持基于 DNS 和基于 RPC 的服务发现。服务提供者使用 原生SDKOpenAPI、或一个独立的Agent TODO注册 Service 后,服务消费者可以使用DNS TODOHTTP&API查找和发现服务。

      Nacos 提供对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求。Nacos 支持传输层 (PING 或 TCP)和应用层 (如 HTTP、MySQL、用户自定义)的健康检查。 对于复杂的云环境和网络拓扑环境中(如 VPC、边缘网络等)服务的健康检查,Nacos 提供了 agent 上报模式和服务端主动检测2种健康检查模式。Nacos 还提供了统一的健康检查仪表盘,帮助您根据健康状态管理服务的可用性及流量。

    • 动态配置服务

      动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。

      动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。

      配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。

      Nacos 提供了一个简洁易用的UI (控制台样例 Demo) 帮助您管理所有的服务和应用的配置。Nacos 还提供包括配置版本跟踪、金丝雀发布、一键回滚配置以及客户端配置更新状态跟踪在内的一系列开箱即用的配置管理特性,帮助您更安全地在生产环境中管理配置变更和降低配置变更带来的风险。

    • 动态 DNS 服务

      动态 DNS 服务支持权重路由,让您更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单DNS解析服务。动态DNS服务还能让您更容易地实现以 DNS 协议为基础的服务发现,以帮助您消除耦合到厂商私有服务发现 API 上的风险。

      Nacos 提供了一些简单的 DNS APIs TODO 帮助您管理服务的关联域名和可用的 IP:PORT 列表.

    • 服务及其元数据管理

      Nacos 能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略、服务的 SLA 以及最首要的 metrics 统计数据。

    第二章 Nacos安装与运行

    2.1、下载Nacos

    下载地址:https://github.com/alibaba/nacos/releases/download/1.4.1/nacos-server-1.4.1.zip

    2.2、解压Nacos

    解压软件:请解压到路径中不包含中文以及空格的目录,Java运行环境为JDK1.8+。

    2.3、运行Nacos

    单机运行:startup.cmd -m standalone

    2.4、访问Nacos

    访问地址:http://localhost:8848/nacos/,登录账号:nacos,登录密码:nacos

    第三章 Nacos作注册中心

    3.1、服务提供者

    3.1.1、创建工程

    在父工程spring-cloud-alibaba-study下创建子项目service-goods

    3.1.2、导入依赖

    pom.xml

    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>
    

    3.1.3、编写配置

    application.yaml

    server:
      port: 7001
    
    management:
      endpoints:
        web:
          exposure:
            include: '*'
    
    spring:
      application:
        name: service-goods
      cloud:
        nacos:
          discovery:
            server-addr: http://localhost:8848
    

    3.1.4、主启动类

    com.caochenlei.ServiceGoodsApplication

    @SpringBootApplication
    public class ServiceGoodsApplication {
        public static void main(String[] args) {
            SpringApplication.run(ServiceGoodsApplication.class, args);
        }
    }
    

    3.1.5、控制器类

    com.caochenlei.controller.GoodsController

    @RestController
    public class GoodsController {
        @Value("${server.port}")
        private Integer port;
    
        @RequestMapping("/goods/findByGid")
        public String findByGid(@RequestParam("gid") String gid) {
            return "server port:" + port + ",findByGid:" + gid;
        }
    }
    

    3.1.6、启动测试

    启动程序:com.caochenlei.ServiceGoodsApplication

    访问地址:http://localhost:8848/nacos

    3.1.7、服务集群

    3.2、服务消费者

    3.2.1、创建工程

    在父工程spring-cloud-alibaba-study下创建子项目service-order

    3.2.2、导入依赖

    pom.xml

    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>
    

    3.2.3、编写配置

    application.yaml

    server:
      port: 8001
    
    management:
      endpoints:
        web:
          exposure:
            include: '*'
    
    spring:
      application:
        name: service-order
      cloud:
        nacos:
          discovery:
            server-addr: http://localhost:8848
    

    3.2.4、主启动类

    com.caochenlei.ServiceOrderApplication

    @SpringBootApplication
    public class ServiceOrderApplication {
        public static void main(String[] args) {
            SpringApplication.run(ServiceOrderApplication.class, args);
        }
    
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    

    3.2.5、控制器类

    com.caochenlei.controller.OrderController

    @RestController
    public class OrderController {
        @Value("${server.port}")
        private Integer port;
    
        @Autowired
        private RestTemplate restTemplate;
    
        @RequestMapping("/order/findByOid")
        public String findByGid(@RequestParam("oid") String oid) {
            String goods = restTemplate.getForObject("http://service-goods/goods/findByGid?gid=1", String.class);
            return "server port:" + port + ",findByOid:" + oid + ",goods:" + goods;
        }
    }
    

    3.2.6、启动测试

    启动程序:com.caochenlei.ServiceOrderApplication

    访问地址:http://localhost:8848/nacos

    访问地址:http://localhost:8001/order/findByOid?oid=0

    访问地址:http://localhost:8001/order/findByOid?oid=0

    通过上边的演示,我们发现,默认就已经有了负载均衡的能力了。

    第四章 Nacos作配置中心

    4.1、创三个配置文件

    application-dev.yaml

    application-test.yaml

    application-prod.yaml

    4.2、修改服务提供者

    4.2.1、导入依赖

    pom.xml

    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        ...
        ...
    </dependencies>
    

    4.2.2、添加配置

    bootstrap.yaml

    spring:
      application:
        name: service-goods
      profiles:
        active: dev #激活开发环境配置
      cloud:
        nacos:
          discovery:
            server-addr: http://localhost:8848
          config:
            server-addr: http://localhost:8848
            prefix: application #指定配置文件的前缀
            file-extension: yaml #指定配置文件的拓展名
            group: DEFAULT_GROUP #指定配置文件所在组
            namespace: public #指定配置文件所在命名空间
    

    4.2.3、修改配置

    application.yaml

    server:
      port: 7001
    
    management:
      endpoints:
        web:
          exposure:
            include: '*'
    

    4.2.4、写控制类

    com.caochenlei.controller.ReadConfigController

    @RestController
    @RefreshScope
    public class ReadConfigController {
        @Value("${myinfo}")
        private String myinfo;
    
        @RequestMapping("/myinfo")
        public String myinfo() {
            return myinfo;
        }
    }
    

    4.2.5、启动测试

    重启服务:ServiceGoodsApplication7001

    重启服务:ServiceGoodsApplication7002

    访问地址:http://localhost:7001/myinfo

    修改配置:myinfo: application-dev.yaml, version=2

    访问地址:http://localhost:7001/myinfo

    4.3、配置的数据模型

    Data Id

    Nacos中的某个配置集合的ID,配置集合ID是组织划分配置的维度之一,Data ID通常用于组织划分系统的配置集合,一个系统或者应用可以包含多个配置集合,每个配置集都可以被一个有意义的名称标识。

    Group

    Nacos中的一组配置集合,是组织配置的维度之一,通过一个有意义的字符串(如 Buy 或 Trade)对一组配置集合进行分组,从而区分Data ID相同的配置集合,当在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP,配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如database_url配置和MQ_topic配置。

    Namespace

    用于配置隔离,不同命名空间下,可以存在相同的Group或Data ID配置,Namespace的常用场景之一是不同环境的配置进行区分隔离,例如开发环境、测试环境和生产环境的资源(如配置、服务)隔离等。

    第五章 Nacos数据持久化

    5.1、持久化介绍

    Nacos默认情况下是采用Apache Derby内嵌数据库进行数据存储,在单机模式时可以使用Nacos嵌入式数据库实现数据存储,但是derby数据库不方便观察数据存储的基本情况,另外,在Nacos集群环境下,如果使用内嵌数据库,就不能保证数据库的一致性,因此,从Nacos 0.7版本开始增加了支持Mysql数据源能力。

    5.2、持久化配置

    5.2.1、安装数据库

    安装数据库,版本要求:5.6.5+,这里我才用官方最新的版本mysql-5.7.33-winx64.zip,在安装之前一定要确保当前计算机中没有安mysql,否则会失败。

    下载mysql

    下载地址,32位:https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.33-win32.zip

    下载地址,64位:https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.33-winx64.zip

    安装mysql

    (1)解压mysql目录

    C:\DevTools\mysql-5.7.33-winx64
    

    (2)创建mysql配置

    C:\DevTools\mysql-5.7.33-winx64\my.ini
    
    [mysql]
    default-character-set=utf8
    
    [mysqld]
    port=3306
    character-set-server=utf8
    default-storage-engine=INNODB
    basedir=C:\\DevTools\\mysql-5.7.33-winx64
    datadir=C:\\DevTools\\mysql-5.7.33-winx64\\data
    

    (3)创建data目录

    C:\DevTools\mysql-5.7.33-winx64\data
    

    (4)使用管理员启动cmd,然后进入到bin目录

    C:\WINDOWS\system32>cd C:\DevTools\mysql-5.7.33-winx64\bin
    C:\DevTools\mysql-5.7.33-winx64\bin>
    

    (5)安装mysql服务

    C:\DevTools\mysql-5.7.33-winx64\bin>mysqld -install mysql
    Service successfully installed.
    

    (6)初始mysql服务

    C:\DevTools\mysql-5.7.33-winx64\bin>mysqld --initialize --user=mysql --console
    ...
    ...
    ...
    2021-02-17T03:55:21.178240Z 1 [Note] A temporary password is generated for root@localhost: Jl3;h1WCnOoS
    

    注意:密码在A temporary password is generated for root@localhost: Jl3;h1WCnOoS

    (7)启动mysql服务

    C:\DevTools\mysql-5.7.33-winx64\bin>net start mysql
    mysql 服务正在启动 .
    mysql 服务已经启动成功。
    

    (8)登录mysql服务

    C:\DevTools\mysql-5.7.33-winx64\bin>mysql -uroot -pJl3;h1WCnOoS
    

    (9)修改root密码

    ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
    

    (10)退出mysql服务

    exit
    

    (11)登录mysql服务

    C:\DevTools\mysql-5.7.33-winx64\bin>mysql -uroot -p123456
    

    卸载mysql

    (1)停止mysql服务

    C:\DevTools\mysql-5.7.33-winx64\bin>net stop mysql
    

    (2)删除mysql服务

    C:\DevTools\mysql-5.7.33-winx64\bin>sc delete mysql
    

    (3)删除mysql目录

    删除 C:\DevTools\mysql-5.7.33-winx64
    

    注意:如果说删除目录不成功,请把所有cmd窗口、文件打开全部关闭,再重新尝试一次。

    5.2.2、导入数据表

    初始化数据库:CREATE DATABASE nacos_config; USE nacos_config;

    导入数据库表:C:\DevTools\nacos\conf\nacos-mysql.sql

    5.2.3、改配置文件

    修改nacos\conf\application.properties

    #*************** Config Module Related Configurations ***************#
    ### If use MySQL as datasource:
    spring.datasource.platform=mysql
    
    ### Count of DB:
    db.num=1
    
    ### Connect URL of DB:
    db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
    db.user.0=root
    db.password.0=123456
    

    5.2.4、重启Nacos

    请重新启动Nacos。

    5.2.5、创配置文件

    application-dev.yaml

    application-test.yaml

    application-prod.yaml

    5.2.6、查看数据库

    第六章 Nacos高可用集群

    6.1、高可用集群介绍

    我们可以看到上边这是一个高可用的Nacos的架构图,而且一般来说,软件是安装到Linux环境中的,且一台机器安装一个软件,端口都是默认的8848。

    但是为了教学的方便,Nginx的集群搭建和Mysql的集群搭建这里就不演示了,我们搭建一个Windows版本的高可用集群:1台Nginx+1台Nacos+1台Mysql。

    Nginx的学习:https://caochenlei.blog.csdn.net/article/details/108300342

    Mysql的学习:https://caochenlei.blog.csdn.net/article/details/107640904

    我们现在已经安装好了mysql数据库,并且也已经配置好了nacos,nacos也已经连接了mysql数据库,而集群版的nacos只需要多一个配置文件就行了,这个配置文件就代表了所有nacos的ip:port。

    6.2、高可用集群搭建

    6.2.1、Nacos集群配置

    cluster.conf.example拷贝一份为cluster.conf

    #it is ip
    #example
    #192.168.16.101:8847
    #192.168.16.102
    #192.168.16.103
    #这里存放的就是所有安装nacos的服务地址,也就是IP:PORT列表,这里只有一台,我就写一个,你有几台就写几,集群最少是3台,这里只是为了演示如何配
    192.168.1.3:8848
    

    6.2.2、Nacos重新启动

    重新启动nacos,启动命令为:startup.cmd

    6.2.3、Nginx负载均衡

    修改文件nginx.conf

    events {
        worker_connections  1024;
    }
    
    http {
        include       mime.types;
        default_type  application/octet-stream;
        sendfile        on;
        
    	#这里写nacos的各个服务器的ip地址和端口号,理论上,最少三台,这里为了演示,就写了一台
    	upstream nacos-cluster{
    		server 192.168.1.3:8848;
    	}
    	
        server {
    		listen 80;
    		server_name localhost;
    		location /{
    			 proxy_pass http://nacos-cluster;                                              
    		}
        }
    }
    

    6.2.4、Nginx软件启动

    C:\DevTools\nginx-1.18.0>nginx.exe -c ./conf/nginx.conf
    

    6.2.5、Nginx访问测试

    浏览器输入:http://localhost/nacos/#/login

    6.2.6、Nginx地址修改

    spring:
      application:
        name: service-goods
      profiles:
        active: dev #激活开发环境配置
      cloud:
        nacos:
          discovery:
            ##正常来说,这个地址你需要修改,但是,这里就不修改了
            server-addr: http://localhost
          config:
            ##正常来说,这个地址你需要修改,但是,这里就不修改了
            server-addr: http://localhost
            prefix: application #指定配置文件的前缀
            file-extension: yaml #指定配置文件的拓展名
            group: DEFAULT_GROUP #指定配置文件所在组
            namespace: public #指定配置文件所在命名空间
    
    展开全文
    qq_38490457 2021-02-17 14:47:24
  • liutengteng130 2017-08-30 22:40:18
  • qq_25215821 2019-09-13 17:17:19
  • fanrenxiang 2017-10-18 16:44:01
  • he1154910941 2019-04-23 11:27:31
  • weixin_43731532 2020-03-11 23:24:35
  • weixin_43885417 2018-12-15 17:25:02
  • moxiaoya1314 2018-04-23 12:33:49
  • lishirong 2016-10-21 11:34:18
  • lxlnulinuli 2018-07-16 17:43:15
  • u012734441 2017-02-27 08:48:16
  • CDW2328 2019-07-05 21:31:36
  • wang386476890 2021-05-10 17:57:33
  • hemin1003 2020-07-13 18:33:45
  • prestigeding 2018-06-01 13:25:27
  • u012734441 2017-03-06 08:45:02
  • dream_broken 2017-07-27 18:25:03
  • l1028386804 2017-05-20 13:02:31
  • hanchao5272 2018-06-03 23:19:29
  • u010391342 2018-03-30 09:19:38
  • prestigeding 2018-05-28 23:31:03
  • qq_38265137 2018-10-16 13:25:41
  • Colton_Null 2018-11-30 15:21:21
  • qq_26566331 2019-01-17 14:07:59

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 759,010
精华内容 303,604
关键字:

服务提供者配置