听说微信搜索《Java鱼仔》会变更强哦!
本文收录于JavaStarter ,里面有我完整的Java系列文章,学习或面试都可以看看哦
(一)前言
如今微服务架构已经被炒的如火如荼,互联网公司况且不说,连我接触的一个国企现在都开始往微服务分布式架构发展。因此,我会通过最近几篇博客介绍目前比较流行的一些微服务组件,其实微服务并没有那么难。如果在跑项目过程中,想要知道整个项目的所有依赖pom文件或者任何疑问,直接联系我即可。
(二)SpringCloudAlibaba
以前一直听人说SpringCloud,现在又冒出来一个Spring Cloud Alibaba,其实Spring Cloud Alibaba是Spring Cloud下的一个子项目。Spring Cloud不是一个新的框架,而是一系列框架的集合,Spring Cloud Alibaba同样如此。按照官方的说法,Spring Cloud Alibaba为分布式应用程序开发提供了一站式解决方案,它包含开发分布式应用程序所需的所有组件,使您可以轻松地使用Spring Cloud开发应用程序,总结一句话,Spring Cloud Alibaba可以让分布式开发更加简单,并且他提供的开源组件也经历了双十一的洗礼,绝对是如今分布式系统开发的首要选择。
SpringCloudAlibaba中的开源组件有:Nacos Discovery、Nacos Config、Sentinel、RocketMQ、Dubbo Spring Cloud。
(三)Nacos
Nacos是alibaba开源的一个动态服务发现、配置管理和服务管理平台,Nacos约等于eureka+springcloudconfig。
所谓服务发现,其实就是指服务的提供者将服务注册到一个统一的平台,服务的消费者从这个统一的平台中获取服务进行调用。
Nacos就提供了这样一个服务注册中心的平台,而且基于SpringBoot开发,十分简单。
所谓配置中心,就是将项目中的一系列配置(那些原本写在application.properties配置),放到一个统一的平台,就不需要给每个微服务都重新配置,也更加方便管理。
以上两点就是Nacos的功能,了解Nacos能做什么之后,接下来就是代码实践了。在此之前先安装Nacos,我用的是linux版本。
给出Nacos的下载地址:我下载的是最新的1.4.1版本
https://github.com/alibaba/nacos/releases
上传到linux系统上后,先部署:
tar-zxvfnacos-server-1.4.1.tar.gz-C/usr/local/
进到/usr/local/,启动服务,单机环境下需要加上参数-m standalone
./startup.sh-mstandalone
可以通过启动的sh文件看到原因:不加standalone参数情况下启动的是集群服务
if [[ "${MODE}"=="standalone" ]]; thenecho"nacos is starting with standalone"elseecho"nacos is starting with cluster"fi
启动后访问:http://ip:8848/nacos/ 即可进入nacos管理页面,默认登陆名和密码都是nacos
(四)Nacos实现服务注册发现中心
4.1 服务注册
Nacos通过简单的注解,就可以快速注册服务,首先Nacos依赖:
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>
在application.properties中配置nacos的地址、用户名以及密码:
server.port=8081spring.application.name=nacos-discovery-provider#单机环境下spring.cloud.nacos.discovery.server-addr=192.168.78.128:8848#集群环境下,地址逗号分开#spring.cloud.nacos.discovery.server-addr=192.168.78.128:8848,192.168.78.129:8848spring.cloud.nacos.username=nacosspring.cloud.nacos.password=nacos
接着在启动类中增加一个开启注解
//开启服务注册发现
在这里实现一个最简单的接口:
publicclassIndexController { "/{name}") (publicStringindex( ("name") Stringname){ return"provider "+name; } }
启动服务后就可以在Nacos的管理页面中看到注入的服务
4.2 调用服务
前面已经把一个服务注册到Nacos,接下来需要用另外一个服务去调用它,调用方式有很多,这里主要介绍两种:由于调用中会用到feign和ribbon,先引入依赖:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId></dependency>
通过RestTemplate调用 首先在启动类中将RestTemplate注入到Bean容器中:
//负载均衡publicRestTemplaterestTemplate(){ returnnewRestTemplate(); }
然后在代码中直接通过服务名称调用即可
publicclassTestController { privateRestTemplaterestTemplate; "/rest/{name}") (publicStringetIndex2( ("name")Stringname){ Stringurl="http://nacos-discovery-provider/"+name; returnrestTemplate.getForObject(url,String.class); } }
通过feign调用
在启动类时开启注解**@EnableFeignClients**
使用方式也很简单,三个步骤
建立对应于服务提供者的接口:
name="nacos-discovery-provider",fallback=TestServiceFallback.class,configuration=FeignConfiguration.class) (publicinterfaceTestService { "/{name}") (Stringindex( ("name") Stringstring); }
TestServiceFallback对应于报错回调
publicclassTestServiceFallbackimplementsTestService{ publicStringindex(Stringstring) { returnnull; } }
FeignConfiguration将回调类注入到Bean容器中
publicclassFeignConfiguration { publicTestServiceFallbacktestServiceFallback(){ returnnewTestServiceFallback(); } }
最后在Controller中调用Feign接口:
publicclassTestController { privateTestServicetestService; "/feign/{str}") (publicStringetIndex3( ("str")Stringstring){ returntestService.index(string); } }
4.3 在代码中获取Nacos服务的数据
有时候在业务逻辑中需要获取到Nacos中服务的列表以及详细信息,可以通过DiscoveryClient来实现
publicclassTestController { privateDiscoveryClientdiscoveryClient; "/services/{services}") (publicObjectgetService( ("services")Stringservices){ log.info(String.valueOf(discoveryClient.getServices())); returndiscoveryClient.getInstances(services); } }
注意点:如果Nacos服务宕机了,以前已经调用过的接口依旧可以被调用,因为Nacos客户端会缓存调用信息。
(五)Nacos作为配置中心
Nacos提供用于存储配置和其他元数据的key/value存储,为分布式系统中的外部化配置提供服务器端和客户端支持。Nacos-config的核心依赖是:
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency>
首先在配置中心新建一行配置
具体内容如下:
如果在SpringBoot项目中要使用配置中心的话,需要新建一个bootstrap.properties配置文件,在配置文件中配置相关信息:
server.port=8084spring.application.name=nacos-discovery-configspring.cloud.nacos.username=nacosspring.cloud.nacos.password=nacosspring.cloud.nacos.discovery.server-addr=192.168.78.128:8848spring.cloud.nacos.config.server-addr=192.168.78.128:8848#如果需要使用yaml格式的,需要在配置文件中进行文件类型扩展#spring.cloud.nacos.config.file-extension=yaml
接着就可以在代码中使用配置文件了,具体如何使用配置文件方式和使用本地配置文件一样,这里介绍一种:
publicclassTestController { "${user.name}") (privateStringname; "${user.addr}") (privateStringaddr; "/config") (publicStringconfig(){ returnname+"----------"+addr; } }
配置中心的多环境版本
在之前使用springboot时,我们会新建多个配置文件,如application-dev.properties、application-test.properties,然后使用spring.profiles.active=dev去激活对应的配置文件。
在Nacos中,同样也可以这样操作,新建一个dev的配置文件:注意命名需要加后缀,不然获取不到
bootstrap.properties中去激活:
spring.profiles.active=dev
这样访问的就是${spring.application.name}-${spring.profiles.active}.${file-extension}文件了。
Nacos服务配置数据模型
Nacos的配置中心在权限隔离上有三个概念,命名空间、组(Group)、Data ID,这三个概念都是用来隔离区分的,可以在代码中指定对应的命名空间、组和Data ID,来获取到唯一的配置文件。
在代码中可以配置命名空间、组信息,从而选择适合该应用的配置文件。
#配置组spring.cloud.nacos.config.group=My_GROUP#配置命名空间spring.cloud.nacos.config.namespace=9464c719-e93b-414f-a904-2f21ec540178
(六)Nacos数据持久化
Nacos中的数据默认是保存在内嵌数据库中的,0.7版本后增加了mysql数据库的支持。新建一个数据库,我这里命名为nacos_config,然后执行官方的sql语句:
/* * Copyright 1999-2018 Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//******************************************//* 数据库全名 = nacos_config *//* 表名称 = config_info *//******************************************/CREATETABLE `config_info` ( `id` bigint(20)NOTNULL AUTO_INCREMENT COMMENT 'id', `data_id` varchar(255)NOTNULL COMMENT 'data_id', `group_id` varchar(255) DEFAULT NULL, `content` longtextNOTNULL COMMENT 'content', `md5` varchar(32) DEFAULT NULL COMMENT 'md5', `gmt_create` datetimeNOTNULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间', `gmt_modified` datetimeNOTNULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间', `src_user` text COMMENT 'source user', `src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip', `app_name` varchar(128) DEFAULT NULL, `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', `c_desc` varchar(256) DEFAULT NULL, `c_use` varchar(64) DEFAULT NULL, `effect` varchar(64) DEFAULT NULL, `type` varchar(64) DEFAULT NULL, `c_schema` text, PRIMARY KEY (`id`), UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';/******************************************//* 数据库全名 = nacos_config *//* 表名称 = config_info_aggr *//******************************************/CREATETABLE `config_info_aggr` ( `id` bigint(20)NOTNULL AUTO_INCREMENT COMMENT 'id', `data_id` varchar(255)NOTNULL COMMENT 'data_id', `group_id` varchar(255)NOTNULL COMMENT 'group_id', `datum_id` varchar(255)NOTNULL COMMENT 'datum_id', `content` longtextNOTNULL COMMENT '内容', `gmt_modified` datetimeNOTNULL COMMENT '修改时间', `app_name` varchar(128) DEFAULT NULL, `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', PRIMARY KEY (`id`), UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租户字段';/******************************************//* 数据库全名 = nacos_config *//* 表名称 = config_info_beta *//******************************************/CREATETABLE `config_info_beta` ( `id` bigint(20)NOTNULL AUTO_INCREMENT COMMENT 'id', `data_id` varchar(255)NOTNULL COMMENT 'data_id', `group_id` varchar(128)NOTNULL COMMENT 'group_id', `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', `content` longtextNOTNULL COMMENT 'content', `beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps', `md5` varchar(32) DEFAULT NULL COMMENT 'md5', `gmt_create` datetimeNOTNULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间', `gmt_modified` datetimeNOTNULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间', `src_user` text COMMENT 'source user', `src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip', `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', PRIMARY KEY (`id`), UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';/******************************************//* 数据库全名 = nacos_config *//* 表名称 = config_info_tag *//******************************************/CREATETABLE `config_info_tag` ( `id` bigint(20)NOTNULL AUTO_INCREMENT COMMENT 'id', `data_id` varchar(255)NOTNULL COMMENT 'data_id', `group_id` varchar(128)NOTNULL COMMENT 'group_id', `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id', `tag_id` varchar(128)NOTNULL COMMENT 'tag_id', `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', `content` longtextNOTNULL COMMENT 'content', `md5` varchar(32) DEFAULT NULL COMMENT 'md5', `gmt_create` datetimeNOTNULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间', `gmt_modified` datetimeNOTNULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间', `src_user` text COMMENT 'source user', `src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip', PRIMARY KEY (`id`), UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag';/******************************************//* 数据库全名 = nacos_config *//* 表名称 = config_tags_relation *//******************************************/CREATETABLE `config_tags_relation` ( `id` bigint(20)NOTNULL COMMENT 'id', `tag_name` varchar(128)NOTNULL COMMENT 'tag_name', `tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type', `data_id` varchar(255)NOTNULL COMMENT 'data_id', `group_id` varchar(128)NOTNULL COMMENT 'group_id', `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id', `nid` bigint(20)NOTNULL AUTO_INCREMENT, PRIMARY KEY (`nid`), UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`), KEY `idx_tenant_id` (`tenant_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';/******************************************//* 数据库全名 = nacos_config *//* 表名称 = group_capacity *//******************************************/CREATETABLE `group_capacity` ( `id` bigint(20)unsignedNOTNULL AUTO_INCREMENT COMMENT '主键ID', `group_id` varchar(128)NOTNULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群', `quota` int(10)unsignedNOTNULL DEFAULT '0' COMMENT '配额,0表示使用默认值', `usage` int(10)unsignedNOTNULL DEFAULT '0' COMMENT '使用量', `max_size` int(10)unsignedNOTNULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值', `max_aggr_count` int(10)unsignedNOTNULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值', `max_aggr_size` int(10)unsignedNOTNULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值', `max_history_count` int(10)unsignedNOTNULL DEFAULT '0' COMMENT '最大变更历史数量', `gmt_create` datetimeNOTNULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间', `gmt_modified` datetimeNOTNULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_group_id` (`group_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';/******************************************//* 数据库全名 = nacos_config *//* 表名称 = his_config_info *//******************************************/CREATETABLE `his_config_info` ( `id` bigint(64)unsignedNOTNULL, `nid` bigint(20)unsignedNOTNULL AUTO_INCREMENT, `data_id` varchar(255)NOTNULL, `group_id` varchar(128)NOTNULL, `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', `content` longtextNOTNULL, `md5` varchar(32) DEFAULT NULL, `gmt_create` datetimeNOTNULL DEFAULT '2010-05-05 00:00:00', `gmt_modified` datetimeNOTNULL DEFAULT '2010-05-05 00:00:00', `src_user` text, `src_ip` varchar(20) DEFAULT NULL, `op_type` char(10) DEFAULT NULL, `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', PRIMARY KEY (`nid`), KEY `idx_gmt_create` (`gmt_create`), KEY `idx_gmt_modified` (`gmt_modified`), KEY `idx_did` (`data_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造';/******************************************//* 数据库全名 = nacos_config *//* 表名称 = tenant_capacity *//******************************************/CREATETABLE `tenant_capacity` ( `id` bigint(20)unsignedNOTNULL AUTO_INCREMENT COMMENT '主键ID', `tenant_id` varchar(128)NOTNULL DEFAULT '' COMMENT 'Tenant ID', `quota` int(10)unsignedNOTNULL DEFAULT '0' COMMENT '配额,0表示使用默认值', `usage` int(10)unsignedNOTNULL DEFAULT '0' COMMENT '使用量', `max_size` int(10)unsignedNOTNULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值', `max_aggr_count` int(10)unsignedNOTNULL DEFAULT '0' COMMENT '聚合子配置最大个数', `max_aggr_size` int(10)unsignedNOTNULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值', `max_history_count` int(10)unsignedNOTNULL DEFAULT '0' COMMENT '最大变更历史数量', `gmt_create` datetimeNOTNULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间', `gmt_modified` datetimeNOTNULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_tenant_id` (`tenant_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表';CREATETABLE `tenant_info` ( `id` bigint(20)NOTNULL AUTO_INCREMENT COMMENT 'id', `kp` varchar(128)NOTNULL COMMENT 'kp', `tenant_id` varchar(128) default '' COMMENT 'tenant_id', `tenant_name` varchar(128) default '' COMMENT 'tenant_name', `tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc', `create_source` varchar(32) DEFAULT NULL COMMENT 'create_source', `gmt_create` bigint(20)NOTNULL COMMENT '创建时间', `gmt_modified` bigint(20)NOTNULL COMMENT '修改时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`), KEY `idx_tenant_id` (`tenant_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';CREATETABLE users ( username varchar(50)NOTNULL PRIMARY KEY, password varchar(500)NOTNULL, enabled booleanNOTNULL);CREATETABLE roles ( username varchar(50)NOTNULL, role varchar(50)NOTNULL, constraint uk_username_role UNIQUE (username,role));CREATETABLE permissions ( role varchar(50)NOTNULL, resource varchar(512)NOTNULL, action varchar(8)NOTNULL, constraint uk_role_permission UNIQUE (role,resource,action));INSERTINTO users (username, password, enabled)VALUES('nacos','$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu',TRUE);INSERTINTO roles (username, role)VALUES('nacos','ROLE_ADMIN');
执行完成后会创建一系列的表,接下来在nacos的配置文件
(conf/application.properties)中配置数据库连接:
spring.datasource.platform=mysql###CountofDB: db.num=1###ConnectURLofDB: db.url.0=jdbc:mysql://192.168.199.170:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTCdb.user.0=rootdb.password.0=123456
配置完成后所有的数据都会放在外部的Mysql中了。
(七)总结
至此,你已经可以将Nacos放到具体的项目中使用了。等真正在项目中用过一段时间后,再去探究它的源码,将会更加简单。你会累是因为你在走上坡路,我是鱼仔,我们下期再见!