I heard that wechat search “Java fish” will change strong oh!

This article is in Java Server, which contains my complete series of Java articles, can be read for study or interview

(1) Preface

Now micro service architecture has been in full swing, not to mention Internet companies, even a state-owned enterprise I contact now began to micro service distributed architecture development. So, I’m going to introduce some of the most popular microservices components in the last few blog posts. Microservices aren’t that hard. If you want to know all the dependent POM files of the whole project or have any questions in the process of running the project, just contact me directly.

(2) SpringCloudAlibaba

I have always heard of SpringCloud, but now there is a SpringCloud Alibaba. In fact, SpringCloud Alibaba is a sub-project of SpringCloud. Spring Cloud is not a new framework, but a collection of frameworks, as is Spring Cloud Alibaba. According to the official statement, Spring Cloud Alibaba provides a one-stop solution for distributed application development. It contains all the components needed to develop distributed applications, making it easy for you to develop applications using Spring Cloud. In a word, Spring Cloud Alibaba can make distributed development easier, and the open source components it provides have also experienced the baptism of Double 11, and are absolutely the primary choice of distributed system development today.

The open source components in SpringCloudAlibaba are: Nacos Discovery, Nacos Config, Sentinel, RocketMQ, Dubbo SpringCloud.

IO /projects/sp…

(3) Nacos

Nacos is an open source platform for dynamic service discovery, configuration management and service management of Alibaba. Nacos is approximately equivalent to Eureka + SpringCloudConfig.

The so-called service discovery actually means that the service provider registers the service to a unified platform, and the service consumer obtains the service from this unified platform for invocation.

Nacos provides such a platform for a service registry, and is simple to develop based on SpringBoot.

A configuration hub is a way to put a set of configurations in a project (those originally written in the application.properties configuration) on a unified platform, so that each microservice does not need to be reconfigured and is easier to manage.

These two points are what Nacos does, and with an understanding of what Nacos can do, it’s time for code practice. To do that, install Nacos, which I used for the Linux version.

Give the download address of Nacos: I downloaded the latest version 1.4.1

https://github.com/alibaba/nacos/releases
Copy the code

After uploading to Linux, deploy:

tar -zxvf nacos-server-1.41..tar.gz -C /usr/local/
Copy the code

In the standalone environment, add -m standalone to the /usr/local/service

./startup.sh -m standalone
Copy the code

You can see the reason from the startup sh file: The cluster service is started without the standalone parameter

if [[ "${MODE}"= ="standalone" ]]; then
    echo "nacos is starting with standalone"
else
    echo "nacos is starting with cluster"
fi
Copy the code

After startup, visit http://ip:8848/nacos/ to enter the nacOS management page. The default login name and password are both nacos

(4) Nacos realizes service registration discovery center

4.1 Service Registration

Nacos can quickly register services with simple annotations. First, Nacos relies on:

<dependency>
   <groupId>com.alibaba.cloud</groupId>
   <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
Copy the code

Configure the address, username, and password of nacOS in application.properties:

server.port=8081Spring. The application. The name = nacos - discovery - the provider # standalone environment spring. Cloud. Nacos. Discovery. The server - addr =192.16878.128.:8848# # cluster environment, address comma-separated spring. Cloud. Nacos. Discovery. The server - addr =192.16878.128.:8848.192.16878.129.:8848

spring.cloud.nacos.username=nacos
spring.cloud.nacos.password=nacos
Copy the code

Then add an open annotation to the start class

@EnableDiscoveryClient // Enable service registration discovery
Copy the code

Implement the simplest interface here:

@RestController
public class IndexController {
    @GetMapping("/{name}")
    public String index(@PathVariable("name") String name){
        return "provider "+name; }}Copy the code

After starting the service, you can see the injected service in the Nacos administration page

4.2 Invoking the Service

Now that a service is registered with Nacos, you need to invoke it with another service. There are many ways to invoke it. Here are two:

<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>
Copy the code

The RestTemplate call first injects the RestTemplate into the Bean container in the startup class:

@LoadBalanced // Load balancing
@Bean
public RestTemplate restTemplate(a){
    return new RestTemplate();
}
Copy the code

It is then called directly from the service name in the code

@Slf4j
@RestController
public class TestController {
    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/rest/{name}")
    public String etIndex2(@PathVariable("name")String name){
        String url="http://nacos-discovery-provider/"+name;
        returnrestTemplate.getForObject(url,String.class); }}Copy the code

Called through feign

Enable the annotation ** @enableFeignClients ** when the class is started

It’s easy to use, three steps

Establish interfaces corresponding to service providers:

@FeignClient(name = "nacos-discovery-provider",fallback = TestServiceFallback.class,configuration = FeignConfiguration.class)
public interface TestService {
    @GetMapping("/{name}")
    String index(@PathVariable("name") String string);
}
Copy the code

TestServiceFallback corresponds to an error callback

public class TestServiceFallback implements TestService{
    @Override
    public String index(String string) {
        return null; }}Copy the code

FeignConfiguration injects the callback class into the Bean container

public class FeignConfiguration {
    @Bean
    public TestServiceFallback testServiceFallback(a){
        return newTestServiceFallback(); }}Copy the code

Finally, call the Feign interface in the Controller:

@Slf4j
@RestController
public class TestController {
    @Autowired
    private TestService testService;
    @GetMapping("/feign/{str}")
    public String etIndex3(@PathVariable("str")String string){
        returntestService.index(string); }}Copy the code

4.3 Obtain Nacos service data in the code

Sometimes, the business logic needs to obtain the list and details of services in Nacos through DiscoveryClient

@Slf4j
@RestController
public class TestController {
    @Autowired
    private DiscoveryClient discoveryClient;
    @GetMapping("/services/{services}")
    public Object getService(@PathVariable("services")String services){
        log.info(String.valueOf(discoveryClient.getServices()));
        returndiscoveryClient.getInstances(services); }}Copy the code

Note: If the Nacos service goes down, previously invoked interfaces can still be invoked because the Nacos client caches the invocation information.

(v) Nacos as the configuration center

Nacos provides key/value stores for storing configuration and other metadata, providing server-side and client-side support for externalizing configuration in distributed systems. The core dependencies of Nacos-Config are:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
Copy the code

Start by creating a new configuration line in the configuration center

The details are as follows:

To use the configuration center in a SpringBoot project, you need to create a new bootstrap.properties configuration file and configure the relevant information in the configuration file:

server.port=8084

spring.application.name=nacos-discovery-config

spring.cloud.nacos.username=nacos
spring.cloud.nacos.password=nacos

spring.cloud.nacos.discovery.server-addr=192.16878.128.:8848
spring.cloud.nacos.config.server-addr=192.16878.128.:8848# if you need to use yaml formats, need in the configuration file for the file type # extension spring. Cloud. Nacos. Config. The file - the extension = yamlCopy the code

You can then use the configuration file in your code in the same way as using a local configuration file. Here is one:

@RestController
public class TestController {
    @Value("${user.name}")
    private String name;
    @Value("${user.addr}")
    private String addr;
    @GetMapping("/config")
    public String config(a){
        return name+"-- -- -- -- -- -- -- -- -- --"+addr; }}Copy the code

Configure multi-environment versions of the center

Before using SpringBoot, we created several configuration files, such as application-dev.properties, application-test.properties, The corresponding profile is then deactivated with spring.profiles. Active =dev.

In Nacos, you can also create a configuration file for dev: note that the name needs to be suffixed otherwise it will not be available

Deactivate in bootstrap.properties:

spring.profiles.active=dev
Copy the code

${spring.application.name}-${spring.profiles. Active}.${file-extension}.

Nacos service configuration data model

Nacos configuration center has three concepts in permission isolation: namespace, Group and Data ID. These three concepts are used for isolation and differentiation. You can specify the corresponding namespace, Group and Data ID in the code to obtain a unique configuration file.

You can configure namespace and group information in the code to select the appropriate configuration file for the application.

# configuration group spring. Cloud. Nacos. Config. The group = # My_GROUP spring configuration namespace. Cloud. Nacos. Config. The namespace = c719 - e93b - 9464414f-a904-2f21ec540178
Copy the code

(6) Nacos data persistence

Data in Nacos is stored in an embedded database by default, and mysql database support has been added since version 0.7. Create a new database, which I’ll call nacOS_config, and execute the official SQL statement:

Licensed under the Apache License, Version 2.0 (the "License"); 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. */

/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/* Database full name = nacos_config */
/* Table name = config_info */
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
CREATE TABLE `config_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(255) DEFAULT NULL,
  `content` longtext NOT NULL COMMENT 'content',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT 'Creation time',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT 'Modification time',
  `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 'Tenant Field',
  `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';

/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/* Database full name = nacos_config */
/* Table name = config_info_AGgr */
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
CREATE TABLE `config_info_aggr` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(255) NOT NULL COMMENT 'group_id',
  `datum_id` varchar(255) NOT NULL COMMENT 'datum_id',
  `content` longtext NOT NULL COMMENT 'content',
  `gmt_modified` datetime NOT NULL COMMENT 'Modification time',
  `app_name` varchar(128) DEFAULT NULL,
  `tenant_id` varchar(128) DEFAULT ' ' COMMENT 'Tenant Field'.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='Add tenant field';


/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/* Database full name = nacos_config */
/* Table name = config_info_beta */
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
CREATE TABLE `config_info_beta` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL COMMENT 'content',
  `beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT 'Creation time',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT 'Modification time',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip',
  `tenant_id` varchar(128) DEFAULT ' ' COMMENT 'Tenant Field'.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';

/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/* Database full name = nacos_config */
/* Table name = config_info_tag */
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
CREATE TABLE `config_info_tag` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `tenant_id` varchar(128) DEFAULT ' ' COMMENT 'tenant_id',
  `tag_id` varchar(128) NOT NULL COMMENT 'tag_id',
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL COMMENT 'content',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT 'Creation time',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT 'Modification time',
  `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';

/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/* Database full name = nacos_config */
/* Table name = config_TAGs_relation */
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
CREATE TABLE `config_tags_relation` (
  `id` bigint(20) NOT NULL COMMENT 'id',
  `tag_name` varchar(128) NOT NULL COMMENT 'tag_name',
  `tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `tenant_id` varchar(128) DEFAULT ' ' COMMENT 'tenant_id',
  `nid` bigint(20) NOT NULL 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';

/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/* Database full name = nacos_config */
/* Table name = group_capacity */
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
CREATE TABLE `group_capacity` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key ID',
  `group_id` varchar(128) NOT NULL DEFAULT ' ' COMMENT 'Group ID, null character for whole cluster ',
  `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Quota, 0 means default',
  `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Usage',
  `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Maximum size of a single configuration, in bytes, with 0 indicating default',
  `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Maximum number of aggregate sub-configurations, where 0 indicates default',
  `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Upper subconfiguration size of a single aggregate data, in bytes, with 0 indicating default.',
  `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Maximum change history',
  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT 'Creation time',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT 'Modification time'.PRIMARY KEY (`id`),
  UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Cluster and Group Capacity Information Table';

/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/* Database full name = nacos_config */
/* Table name = his_config_info */
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
CREATE TABLE `his_config_info` (
  `id` bigint(64) unsigned NOT NULL,
  `nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `data_id` varchar(255) NOT NULL,
  `group_id` varchar(128) NOT NULL,
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL,
  `md5` varchar(32) DEFAULT NULL,
  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
  `gmt_modified` datetime NOT NULL 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 'Tenant Field'.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='Multi-tenant Conversion';


/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/* Database full name = nacos_config */
/* Table name = tenant_capacity */
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
CREATE TABLE `tenant_capacity` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key ID',
  `tenant_id` varchar(128) NOT NULL DEFAULT ' ' COMMENT 'Tenant ID',
  `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Quota, 0 means default',
  `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Usage',
  `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Maximum size of a single configuration, in bytes, with 0 indicating default',
  `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Maximum number of aggregate sub-configurations',
  `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Upper subconfiguration size of a single aggregate data, in bytes, with 0 indicating default.',
  `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Maximum change history',
  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT 'Creation time',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT 'Modification time'.PRIMARY KEY (`id`),
  UNIQUE KEY `uk_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Tenant Capacity Information Table';


CREATE TABLE `tenant_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `kp` varchar(128) NOT NULL 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) NOT NULL COMMENT 'Creation time',
  `gmt_modified` bigint(20) NOT NULL COMMENT 'Modification time'.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';

CREATE TABLE users (
	username varchar(50) NOT NULL PRIMARY KEY,
	password varchar(500) NOT NULL,
	enabled boolean NOT NULL
);

CREATE TABLE roles (
	username varchar(50) NOT NULL,
	role varchar(50) NOT NULL.constraint uk_username_role UNIQUE (username,role)
);

CREATE TABLE permissions (
    role varchar(50) NOT NULL,
    resource varchar(512) NOT NULL,
    action varchar(8) NOT NULL.constraint uk_role_permission UNIQUE (role,resource,action)
);

INSERT INTO users (username, password, enabled) VALUES ('nacos'.'$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu'.TRUE);

INSERT INTO roles (username, role) VALUES ('nacos'.'ROLE_ADMIN');

Copy the code

Execution is created after the completion of a series of tables, in the configuration file nacos (conf/application. The properties) in the configuration database connection:

spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url. 0=jdbc:mysql:/ / 192.168.199.170:3306 / nacos_config? characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTime zone=UTC
db.user. 0=root
db.password. 0=123456
Copy the code

After configuration, all data will be stored in external Mysql.

(7) Summary

At this point, you are ready to use Nacos in specific projects. It will be much easier to explore the source code after you have actually used it in a project for a while. You’re tired because you’re walking uphill. I’m fish boy. See you next time!