Dapr (* * D * * distributed application runtime) is an open source, portable and event driven runtime. It enables developers to easily build elastic and micro service applications running on cloud platforms and edges, whether stateless or stateful. Dapr enables developers to focus on writing business logic rather than solving the challenges of distributed systems, thereby significantly improving productivity and reducing development time. In addition, dapr also reduced the entry threshold for most small and medium-sized enterprises to build modern cloud native applications based on micro service architecture.
The core building blocks of Dapr are as follows:
- Service invocation: elastic service to service invocation enables method invocation on a remote service, including retry, regardless of where the remote service is running in a supported managed environment.
- State management: through the state management of key / value pairs, it is easy to write stateful services that run for a long time and have high availability, as well as stateless services in the same application. The state store is pluggable and can include Azure Cosmos or Redis , and other components on the component roadmap, such as AWS DynamoDB, etc.
- Publish and subscribe to messages between services (Pub/Sub): enable event driven architecture to simplify horizontal scalability and enable failure recovery.
- Event driven resource binding: resource binding and trigger are further built on the event driven architecture. They can realize scalability and elasticity by receiving and sending events from any external resources (such as database, queue, file system, blob storage, webhooks, etc.). For example, your code can be triggered by a message on the Azure EventHub service and write the data to Azure CosmosDB.
- Virtual role: the pattern of stateless and stateful objects, which makes concurrency simple through method and state encapsulation. Dapr provides many functions when its Virtual Actors are running, including concurrency, status, life cycle management of role activation / deactivation, and timers and reminders for waking up roles.
- Distributed tracking between services: use W3C Trace Context standard to easily diagnose and observe inter service calls in production, and push events to the tracking and monitoring system.
Today, we simply use Dapr to complete the calling process of a microservice.
I. environmental preparation
1.1. Install Docker (default Hyper-v must be enabled for windows 10)
We are preparing a CentOS 7 6 virtual machine. docker installation is relatively simple. Please see another article Centos7.6. Install Docker CE
1.2. Installation NET Core SDK6.0
# Add trusted source rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm # Install NET 6 SDK yum install dotnet-sdk-6.0
Please see my blog for detailed installation steps Centos7.6 install the latest DotNet6 development environment
1.3 installation of Dapr
1.3.1 download the package file first
Let's go Dapr-CLI Download Dapr from this address. The latest version is Dapr CLI v1.6.0 , pay attention to the amd64 bit under linux
wget -c https://github.com/dapr/cli/releases/download/v1.6.0/dapr_linux_amd64.tar.gz
1.3.2 decompress after downloading
Here we unzip it to the / usr/local/bin directory
tar xf /export/server/dapr_linux_amd64.tar.gz -C /usr/local/bin
Before decompression, there is only one sqlite3
After decompression, please pay attention to the execution permission of dapr. If there is no execution permission, you need to add Chmod X/ dapr
After decompression, we directly execute dapr and install it as follows
1.3.3 initialize Dapr
It's not enough to install it. Because Dapr runs based on Docker, let's initialize Dapr
dapr init
Here, because I don't have wall climbing software, the download of the package will fail. I have tried it several times successfully. If an error is reported, I can execute the uninstall command and reinitialize
dapr uninstall dapr init
Check the initialization result docker ps. there are the following three containers to prove that dapr is running
II. Test interface
2.1 new webapi project
There are two api projects, one school api and one professional api
Next, in two projects, we use NuGet package manager to introduce dapr AspNetCore
The interface logic we tested is that the school service calls the specialty list data from the specialty service
School interface
Professional interface, simulating 5 pieces of professional information
2.2 release items
For important configuration before release, we added the project release as the project identified by Dapr in the Program configuration of the two api projects
builder.Services.AddControllers().AddDapr();
We release 2 projects
2.3 upload server
Here I use xftp to upload to the server where dapr is located
2.4 running major microservices
We cd to the root directory of major microservice_ Under publish, execute
dapr run --app-id MajorService --app-port 9910 --dapr-http-port 19910 -- dotnet MajorMis.Api.dll --urls "http://*:9910"
The following information proves that the startup is successful
[root@node2 bin]# cd /export/server/Net6/ You have new mail in /var/spool/mail/root [root@node2 Net6]# ll total 8 drwxr-xr-x 2 root root 4096 Mar 6 21:11 major_publish drwxr-xr-x 2 root root 4096 Mar 6 21:12 school_publish [root@node2 Net6]# cd major_publish/ [root@node2 major_publish]# dapr run --app-id MajorService --app-port 9910 --dapr-http-port 19910 -- dotnet MajorMis.Api.dll --urls "http://*:9910" ℹ️ Starting Dapr with id MajorService. HTTP Port: 19910. gRPC Port: 40410 INFO[0003] starting Dapr Runtime -- version 1.6.0 -- commit 4bb25fab444c4f1a1bf0ffd74293dbd4fdcea580 app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0003] log level set to: info app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0003] metrics server started on :44214/ app_id=MajorService instance=node2 scope=dapr.metrics type=log ver=1.6.0 INFO[0003] standalone mode configured app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0003] app id: MajorService app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0003] mTLS is disabled. Skipping certificate request and tls validation app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0004] local service entry announced: MajorService -> 192.168.88.101:43238 app_id=MajorService instance=node2 scope=dapr.contrib type=log ver=1.6.0 INFO[0004] Initialized name resolution to mdns app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0004] loading components app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0008] component loaded. name: pubsub, type: pubsub.redis/v1 app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0008] waiting for all outstanding components to be processed app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0008] detected actor state store: statestore app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0008] component loaded. name: statestore, type: state.redis/v1 app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0008] all outstanding components processed app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0008] enabled gRPC tracing middleware app_id=MajorService instance=node2 scope=dapr.runtime.grpc.api type=log ver=1.6.0 INFO[0008] enabled gRPC metrics middleware app_id=MajorService instance=node2 scope=dapr.runtime.grpc.api type=log ver=1.6.0 INFO[0008] API gRPC server is running on port 40410 app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0008] enabled metrics http middleware app_id=MajorService instance=node2 scope=dapr.runtime.http type=log ver=1.6.0 INFO[0008] enabled tracing http middleware app_id=MajorService instance=node2 scope=dapr.runtime.http type=log ver=1.6.0 INFO[0008] http server is running on port 19910 app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0008] The request body size parameter is: 4 app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0008] enabled gRPC tracing middleware app_id=MajorService instance=node2 scope=dapr.runtime.grpc.internal type=log ver=1.6.0 INFO[0008] enabled gRPC metrics middleware app_id=MajorService instance=node2 scope=dapr.runtime.grpc.internal type=log ver=1.6.0 INFO[0008] internal gRPC server is running on port 43238 app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0008] application protocol: http. waiting on port 9910. This will block until the app is listening on that port. app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0010] application discovered on port 9910 app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 == APP == info: Microsoft.Hosting.Lifetime[14] == APP == Now listening on: http://[::]:9910 == APP == info: Microsoft.Hosting.Lifetime[0] == APP == Application started. Press Ctrl+C to shut down. == APP == info: Microsoft.Hosting.Lifetime[0] == APP == Hosting environment: Production == APP == info: Microsoft.Hosting.Lifetime[0] == APP == Content root path: /export/server/Net6/major_publish/ INFO[0010] application configuration loaded app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0010] actor runtime started. actor idle timeout: 1h0m0s. actor scan interval: 30s app_id=MajorService instance=node2 scope=dapr.runtime.actor type=log ver=1.6.0 INFO[0010] dapr initialized. Status: Running. Init Elapsed 7042.741769ms app_id=MajorService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0011] placement tables updated, version: 0 app_id=MajorService instance=node2 scope=dapr.runtime.actor.internal.placement type=log ver=1.6.0 ℹ️ Updating metadata for app command: dotnet MajorMis.Api.dll --urls http://*:9910 ✅ You're up and running! Both Dapr and your app logs will appear here.
When we visit the browser, we can find professional information. Here is a pit. Note: the service name (MajorService) is case sensitive
http://192.168.88.101:19910/v1.0/invoke/MajorService/method/major
Next, we start the school microservice to call the list data of professional microservices, open a new shell terminal, and cd to the school service publishing directory school_publish, terminal execution:
dapr run --app-id SchoolService --app-port 9920 --dapr-http-port 19920 -- dotnet SchoolMis.Api.dll --urls "http://*:9920"
You're up and running! Both Dapr and your app logs will appear here. Successfully started
[root@node2 Net6]# cd school_publish/ [root@node2 school_publish]# dapr run --app-id SchoolService --app-port 9920 --dapr-http-port 19920 -- dotnet SchoolMis.Api.dll --urls "http://*:9920" ℹ️ Starting Dapr with id SchoolService. HTTP Port: 19920. gRPC Port: 42086 INFO[0002] starting Dapr Runtime -- version 1.6.0 -- commit 4bb25fab444c4f1a1bf0ffd74293dbd4fdcea580 app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0002] log level set to: info app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0002] metrics server started on :32846/ app_id=SchoolService instance=node2 scope=dapr.metrics type=log ver=1.6.0 INFO[0002] standalone mode configured app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0002] app id: SchoolService app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0002] mTLS is disabled. Skipping certificate request and tls validation app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0002] local service entry announced: SchoolService -> 192.168.88.101:37447 app_id=SchoolService instance=node2 scope=dapr.contrib type=log ver=1.6.0 INFO[0002] Initialized name resolution to mdns app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0002] loading components app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0002] component loaded. name: pubsub, type: pubsub.redis/v1 app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0002] waiting for all outstanding components to be processed app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0002] detected actor state store: statestore app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0002] component loaded. name: statestore, type: state.redis/v1 app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0002] all outstanding components processed app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0002] enabled gRPC tracing middleware app_id=SchoolService instance=node2 scope=dapr.runtime.grpc.api type=log ver=1.6.0 INFO[0002] enabled gRPC metrics middleware app_id=SchoolService instance=node2 scope=dapr.runtime.grpc.api type=log ver=1.6.0 INFO[0002] API gRPC server is running on port 42086 app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0002] enabled metrics http middleware app_id=SchoolService instance=node2 scope=dapr.runtime.http type=log ver=1.6.0 INFO[0002] enabled tracing http middleware app_id=SchoolService instance=node2 scope=dapr.runtime.http type=log ver=1.6.0 INFO[0002] http server is running on port 19920 app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0002] The request body size parameter is: 4 app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0002] enabled gRPC tracing middleware app_id=SchoolService instance=node2 scope=dapr.runtime.grpc.internal type=log ver=1.6.0 INFO[0002] enabled gRPC metrics middleware app_id=SchoolService instance=node2 scope=dapr.runtime.grpc.internal type=log ver=1.6.0 INFO[0002] internal gRPC server is running on port 37447 app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0002] application protocol: http. waiting on port 9920. This will block until the app is listening on that port. app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0002] application discovered on port 9920 app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 == APP == info: Microsoft.Hosting.Lifetime[14] == APP == Now listening on: http://[::]:9920 ℹ️ Updating metadata for app command: dotnet SchoolMis.Api.dll --urls http://*:9920 ✅ You're up and running! Both Dapr and your app logs will appear here. == APP == info: Microsoft.Hosting.Lifetime[0] == APP == Application started. Press Ctrl+C to shut down. == APP == info: Microsoft.Hosting.Lifetime[0] == APP == Hosting environment: Production == APP == info: Microsoft.Hosting.Lifetime[0] == APP == Content root path: /export/server/Net6/school_publish/ INFO[0003] application configuration loaded app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0003] actor runtime started. actor idle timeout: 1h0m0s. actor scan interval: 30s app_id=SchoolService instance=node2 scope=dapr.runtime.actor type=log ver=1.6.0 INFO[0003] dapr initialized. Status: Running. Init Elapsed 1296.726341ms app_id=SchoolService instance=node2 scope=dapr.runtime type=log ver=1.6.0 INFO[0003] placement tables updated, version: 0 app_id=SchoolService instance=node2 scope=dapr.runtime.actor.internal.placement type=log ver=1.6.0
Next, call the professional micro service with the school service. We request the default get interface of the school service, and you can see the returned professional list json data
http://192.168.88.101:19910/v1.0/invoke/SchoolService/method/school
Note the code of the school service get request. We are a professional micro service called through daprclient
[HttpGet] public async Task<IEnumerable<MajorInfo>> Get() { _logger.LogInformation("[start] Query professional information from professional microservices"); // Remotely call the commodity micro service to obtain all Sku information var majors = await _daprClient.InvokeMethodAsync<IEnumerable<MajorInfo>> (HttpMethod.Get, "MajorService", "Major"); _logger.LogInformation($"[end] The information queried from professional microservices is: {majors.ToArray()?.ToString()}"); return majors; }
Logs can also prove
The school micro service log is printed as follows
The professional micro service log is printed as follows
Then we execute the command dapr list to view the services running under dapr, and you can see the information of two micro services
Today's actual combat is here. Friends who need source code please pay attention to my official account, and I can get back to Dapr.
Summary
Thank you for seeing here 😉
That's all for this sharing. Owl data is committed to sharing technology dry goods for you 😎
If there are any mistakes in the above process, please correct them 😅
Friends who benefit or partners who are interested in technology remember to praise, pay attention to and support a wave 🙏
You can also scan the two-dimensional code or search for my WeChat official account, owl data analysis. 🙏