Solon Cloud Distributed Development Suite checklist and quick overview

Posted by emmbec on Tue, 07 Dec 2021 06:58:00 +0100

Solon Cloud is a series of interface standards and configuration specifications. Solon Cloud provides a simple and convenient programming mode for common distributed system modes to help developers build elastic, reliable and coordinated applications. Solon Cloud is built on Solon, which makes it easy for developers to start and quickly apply it to production. Solon Cloud is mainly composed of three parts: interface definition and configuration specification, various plug-ins implementing relevant interface definitions, and general client.

Solon Cloud is very easy to connect with the self-developed framework. As long as the relevant interface definitions are implemented, a plug-in configured according to the specification is a Solomon cloud plug-in.

Solon Cloud project source code:  
https://gitee.com/noear/solon

Solon Cloud sample source code:  
https://gitee.com/noear/solon_cloud_demo

Feature 1: slim figure

The smallest Solon Cloud development unit is only 4m (including okhttp, mysql, redis, memcached, HikariCP and other clients or drivers)

Feature 2: faster

Native HelloWorld test, Qps up to 120000. For reference: helloworld_wrk_test

Feature 3: Code freedom

All abilities can be annotated or handwritten. On demand, free.

proposal

Enable your own single application to be deployed in multiple instances. It's a good start for distribution... Then switch to configuration services, then add event driven, split on demand... Take your time.

1, Solon Cloud suite content

(1) Interface definition and configuration specification list

The interface definition and configuration specification can provide a unified mode for the adaptation and use of different frameworks

Function name

Solon Cloud

Interface definition

Configuration specification (details omitted)

Service registration and discovery

Solon Cloud Discovery

CloudDiscoveryService

solon.cloud.@@.discovery

Inter service call mode

RPC or REST API or Event

-

-

Service gateway

Solon Gateway

-

-

Circuit breaker

Solon Cloud Breaker

CloudBreakerService

solon.cloud.@@.breaker

Distributed configuration

Solon Cloud Config

CloudConfigService

solon.cloud.@@.config

Service tracking

Solon Cloud Tracing

CloudTraceService

solon.cloud.@@.trace

Event bus

Solon Cloud Event

CloudEventService

solon.cloud.@@.event

Distributed task

Solon Cloud Job

CloudJobService

solon.cloud.@@.job

Distributed ID

Solon Cloud Id

CloudIdService

solon.cloud.@@.id

Distributed file

Solon Cloud File

CloudFileService

solon.cloud.@@.file

Distributed list

Solon Cloud List

CloudListService

solon.cloud.@@.list

Distributed lock

Solon Cloud Lock

CloudLockService

solon.cloud.@@.lock

Distributed log

Solon Cloud Logging

CloudLogService

solon.cloud.@@.log

(2) List of existing adapters

plug-in unit

explain

External frame adaptation:

explain

org.noear:consul-solon-plugin

Consumer adapter plug-in (supporting Solon cloud configuration service, registration and discovery service)

org.noear:nacos-solon-plugin

nacos adapter plug-in (supporting Solon cloud configuration service, registration and discovery service)

org.noear:zookeeper-solon-plugin

zookeeper adapter plug-in (supports Solon cloud configuration service, registration and discovery service)

org.noear:water-solon-plugin

water adapter plug-in (supports Solon cloud configuration service, registration and discovery service, event bus service, log service, tracking service and lock service)

org.noear:rabbitmq-solon-plugin

rabbitmq adapter plug-in (supporting Solon cloud event bus service)

org.noear:rocketmq-solon-plugin

rocketmq adapter plug-in (supporting Solon cloud event bus service)

org.noear:mqtt-solon-plugin

mqtt adapter plug-in (supporting Solon cloud event bus service)

org.noear:kafka-solon-plugin

kafka adapter plug-in (supporting Solon cloud event bus service)

org.noear:guava-solon-plugin

guava adapter plug-in (supporting Solon cloud disconnection service)

org.noear:sentinel-solon-plugin

sentinel adapter plug-in (supporting Solon cloud disconnection service)

org.noear:semaphore-solon-plugin

semaphore adapter plug-in (supporting Solon cloud disconnection service)

org.noear:aliyun-oss-solon-plugin

Aliyun OSS adapter plug-in (supporting solo cloud distributed file service)

org.noear:aws-s3-solon-plugin

aws-s3 adapter plug-in (supporting Solon cloud distributed file service)

org.noear:snowflake-id-solon-plugin

snowflake algorithm adaptation plug-in (supporting solo cloud distributed ID service)

(3) General client

The general client provides a unified user interface for all different frameworks and a free manual control mechanism.

//Get the configuration manually (no matter which configuration framework is behind it)
 Config val1 = CloudClient.config().pull(Solon.cfg().appGroup(), "demo.ds");
 
 //Generate ID manually
 long val2 = CloudClient.id().generate();
 
 //Manually publish events (no matter which message queue is behind it)
 CloudClient.event().publish(new Event("demo.user.login","1"));
 
 //Wait

2, Quick overview

(1)hello world

A common rest api that outputs hello world

public class DemoApp {
    public static void main(String[] args) {
        Solon.start(DemoApp.class, args, app->{
          app.get("/", c -> c.output("Hello world!"));
        });
    }
}

(2) Using configuration services

Import the required distributed configuration through local configuration

solon.cloud.water:
  server: water  
  config:
    load: "test.properties" #A configuration is loaded by default

Alternatively, use the @ CloudConfig annotation to generate beans

@Configuration
public class Config {
    @Bean
    public DataSource ds(@CloudConfig("demo.ds") HikariDataSource ds){
        return ds;
    }
}

(3) Implementing RPC calls using registration and discovery services

Server

//
// 1. All components with remoting = true are rpc services;
// 2. Provide resource description in the form of uri to support both rest api and rpc modes
//
@Mapping("/rpc/")
@Component(remoting = true)
public class HelloServiceImpl implements HelloService{

    @Override
    public String hello(String name) {
        return null;
    }
}

client

@Controller
public class HelloController {
    //Inject Rpc service agent (automatically obtain service cluster through discovery service)
    @NamiClient(name = "hellorpc", path = "/rpc/")
    HelloService helloService;
    
    public String hello(String name){
        return helloService.hello(name);
    }
}

(4) Use the Slf4j log interface to forward to the distributed logger

Solon Cloud Log emphasizes semantic tags (or solidified meta information). Through semantic tags, the logs are fixed indexed to achieve faster query results.

@Slf4j
public class LogController {
    @Mapping("/")
    public String hello(String name){
        //Solidify meta information into tag0... Tag4; Facilitate log indexing
        TagsMDC.tag0("user_"+name); //Equivalent to MDC.put("tag0", "user_"+name);
        
        log.info("There are users coming");
        
        return name;
    }
}

Note: you can also use   logback   For log service, you only need to eliminate it   solon.logging.impl   The framework can

(5) Business level expansion using distributed events

Two features of Solon Cloud Event:

  1. Self guard mode, i.e. continuous delayed retransmission after failure to ensure final success. This feature supports SAGA distributed transaction model.
  2. Multi channel mode, that is, different message queues coexist. This feature can be arranged differently according to business. For example, RabbitMQ is used for business messages and Mqtt is used for IoT messages.

For example, publish events

public class EventController {
    public void onUserRegistered(long user_id) {
        //After the user registration is completed, an event is published
        //
        CloudClient.event().publish(
                new Event("user.registered", String.format("{\"user_id\":%d}", user_id)));
    }
}

Subscription and consumption events

@CloudEvent("user.registered")
public class EventListen implements CloudEventHandler {
    @Override
    public boolean handler(Event event) throws Throwable {
        //After the user registration is completed, send a gold coin
        //
        return true;
    }
}

(6) Use distributed list for IP restriction

public class ListController {
    public void hello(Context ctx){
        String ip = IpUtils.getIP(ctx);
        
        if(CloudClient.list().inListOfIp("safelist", ip) == false){
            return;
        }
        
        //Business processing
    }
}

(7) Current limiting control with fuse

Add configuration (this configuration can be dynamically updated through configuration service)

solon.cloud.local:
  breaker:
    main: 100 #qps = 100

Add buried points through annotations

//The name of the buried point in the annotation here must correspond to the name of the configured circuit breaker one by one
@CloudBreaker("main")
public class BreakerController {
    @Mapping("/breaker")
    public void breaker(){
        
    }
}

(8) Get and propagate TraceId using tracking service

Pass to slf4j MDC through MDC

String traceId = CloudClient.trace().getTraceId();

MDC.put(CloudClient.trace().HEADER_TRACE_ID_NAME(), traceId);

Passed to the post Http node through the Http Header

HttpUtils.url("http://x.x.x.x")
  .headerAdd(CloudClient.trace().HEADER_TRACE_ID_NAME(), traceId).get();

Etc... (Solon Cloud Log supports CloudClient.trace() interface by default)

(9) Use distributed IDS to generate ordered non duplicate IDs

long log_id = CloudClient.id().generate();

(10) Use distributed locks to control traffic or resources

if(CloudClient.lock().lock("user_"+user_id, 3)){
    //Try to lock a user for 3 seconds; Repeated submission without full line within 3 seconds
}else{
    //Requests are too frequent
}

(11) Using distributed file services

//Use distributed files to store user extension information
CloudClient.file().putText("solon/user_"+user_id, "{name:noear}")

(12) Use gateway to provide different outputs for the same set of interfaces

//Gateway 1
@Mapping("/api/rest/**")
@Component
public class ApiGateway extends Gateway {
    @Override
    protected void register() {
        //Set default render
        before(c -> c.attrSet("@render", "@json"));

        //Add service
        add("user", UserServiceImpl.class, true);

    }
}

//Gateway 2
@Mapping("/api/rpc/**")
@Component
public class RpcGateway extends Gateway {
    @Override
    protected void register() {
        //Set default render
        before(c -> c.attrSet("@render", "@type_json"));

        //Add a service (function without mapping; remoting = true is required to load it)
        add("user", UserServiceImpl.class, true);
    }
}

3, Attachment: complete configuration

application.yml

solon.app:
  group: demo       #Configure the default group used by the service
  name: helloapp    #Application name used by discovery service

solon.cloud.water:
  server: water   #water service address
  config:
    load: "test.properties" #A configuration is loaded by default
  discovery:
    enable: true  #When set to false, solo.cloud.local.discovery will take effect (generally used for local debugging)

solon.cloud.local:
  discovery:
    service:
      hellorpc:
        - "http://localhost:7112 "# local service configuration
  breaker:
    main: 100

pom.xml (the following configuration size is only 4.7m)

<parent>
    <groupId>org.noear</groupId>
    <artifactId>solon-parent</artifactId>
    <version>1.3.32</version>
</parent>

<dependencies>
    <!-- RPC frame -->
    <dependency>
        <groupId>org.noear</groupId>
        <artifactId>solon-rpc</artifactId>
    </dependency>

    <!-- Configuration service, registration and discovery service, log service, lock service, list service and tracking service... (contain okhttp,redis,memcaced,HikariCP etc....) -->
    <dependency>
        <groupId>org.noear</groupId>
        <artifactId>water-solon-plugin</artifactId>
    </dependency>

    <!-- Breaking service -->
    <dependency>
        <groupId>org.noear</groupId>
        <artifactId>sentinel-solon-plugin</artifactId>
    </dependency>

    <!-- File service -->
    <dependency>
        <groupId>org.noear</groupId>
        <artifactId>aliyun-oss-solon-plugin</artifactId>
    </dependency>

    <!-- ID service -->
    <dependency>
        <groupId>org.noear</groupId>
        <artifactId>snowflake-id-solon-plugin</artifactId>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.49</version>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

<build>
    <finalName>${project.artifactId}</finalName>

    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.7.0</version>
            <configuration>
                <compilerArgument>-parameters</compilerArgument>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.3.0</version>
            <configuration>
                <finalName>${project.artifactId}</finalName>
                <appendAssemblyId>false</appendAssemblyId>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <archive>
                    <manifest>
                        <mainClass>demo.DemoApp</mainClass>
                    </manifest>
                </archive>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>

</build>

 

Topics: Java Spring Boot Programmer Spring Cloud