当前位置:网站首页>InfoQ geek media's 15th anniversary solicitation of papers | design practice of micro service architecture in the cloud native Era
InfoQ geek media's 15th anniversary solicitation of papers | design practice of micro service architecture in the cloud native Era
2022-06-09 15:14:00 【InfoQ】
Preface
Microservice architecture
History of microservices
- High complexity
- The cost of teamwork is high
- Expandability of
- Inefficient deployment
- Poor high availability of the system
- Single function
- Service granularity is small
- Strong independence between services
- Weak dependence between services
- Service independent maintenance
- Service independent deployment
Granularity of microservice segmentation

Containerization Technology
What is a container

Kubernetes
K8s Why does it become the infrastructure of microservices
Why? K8s It is the foundation of the next generation microservice architecture
- Master-slave mode , It works by : The host is working , Standby is under monitoring 、 Ready to go , When the host goes down , The standby machine can take over all the work of the host machine , When the host is back to normal , The service will be switched to the host manually or automatically , Data consistency is achieved through shared storage .
- The cluster approach , It works by : Multiple machines running one or more services at the same time , When one of the nodes goes down , At this time, the service of the node will not be able to provide business functions , You can choose according to a certain mechanism , Transfer the service request to other nodes where the service is located , This allows the logic to continue to execute , That is to eliminate software single point of failure . This actually involves load balancing strategy .
apiVersion: v1
kind: Service
metadata:
name: test
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
app=MyAppkind: ConfigMap
apiVersion: v1
metadata:
name: rest-service
namespace: system-server
data:
application.yaml: |-
greeting:
message: Say Hello to the World
---
spring:
profiles: dev
greeting:
message: Say Hello to the Developers

K8s The foundation and actual combat
K8s Basics
kubectl create -f xxx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-deployment
spec:
selector:
matchLabels:
app: tomcat
replicas: 2
template:
metadata:
labels:
app: tomcat
spec:
containers:
- name: tomcat
image: tomcat:10.0.5
ports:
- containerPort: 80
[email protected]:~/damon$ kubectl create -f tomcat-deployment.yaml
deployment.apps/tomcat-deployment created
[email protected]:~/damon$ kubectl get pod -l app=tomcat
NAME READY STATUS RESTARTS AGE
tomcat-deployment-799f46f546-7nxrj 1/1 Running 0 77s
tomcat-deployment-799f46f546-hp874 0/1 Running 0 77s
kubectl get-lkubectl describe[email protected]:~/damon$ kubectl describe pod tomcat-deployment-799f46f546-7nxrj
Name: tomcat-deployment-799f46f546-7nxrj
Namespace: default
Priority: 0
Node: ca005/10.10.2.5
Start Time: Thu, 08 Apr 2021 10:41:08 +0800
Labels: app=tomcat
pod-template-hash=799f46f546
Annotations: cni.projectcalico.org/podIP: 20.162.35.234/32
Status: Running
IP: 20.162.35.234
Controlled By: ReplicaSet/tomcat-deployment-799f46f546
Containers:
tomcat:
Container ID: docker://5a734248525617e950b7ce03ad7a19acd4ffbd71c67aacd9e3ec829d051b46d3
Image: tomcat:10.0.5
Image ID: docker-pullable://[email protected]:2637c2c75e488fb3480492ff9b3d1948415151ea9c503a496c243ceb1800cbe4
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Thu, 08 Apr 2021 10:41:58 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-2ww52 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-2ww52:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-2ww52
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 4m17s default-scheduler Successfully assigned default/tomcat-deployment-799f46f546-7nxrj to ca005
Normal Pulling 4m16s kubelet, ca005 Pulling image "tomcat:10.0.5"
Normal Pulled 3m27s kubelet, ca005 Successfully pulled image "tomcat:10.0.5"
Normal Created 3m27s kubelet, ca005 Created container tomcat
Normal Started 3m27s kubelet, ca005 Started container tomcat
spec:
containers:
- name: tomcat
image: tomcat:latest
ports:
- containerPort: 80
kubectl apply -f tomcat-deployment.yaml
[email protected]:~/damon$ kubectl logs -f tomcat-deployment-799f46f546-7nxrj
NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
08-Apr-2021 02:41:59.037 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name: Apache Tomcat/10.0.5
08-Apr-2021 02:41:59.040 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built: Mar 30 2021 08:19:50 UTC
08-Apr-2021 02:41:59.040 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 10.0.5.0
08-Apr-2021 02:41:59.040 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name: Linux
08-Apr-2021 02:41:59.040 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version: 4.4.0-116-generic
08-Apr-2021 02:41:59.040 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture: amd64
08-Apr-2021 02:41:59.040 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home: /usr/local/openjdk-11
08-Apr-2021 02:41:59.040 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version: 11.0.10+9
08-Apr-2021 02:41:59.040 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor: Oracle Corporation
08-Apr-2021 02:41:59.040 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: /usr/local/tomcat
08-Apr-2021 02:41:59.041 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: /usr/local/tomcat
08-Apr-2021 02:41:59.051 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED
08-Apr-2021 02:41:59.051 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED
08-Apr-2021 02:41:59.051 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.util=ALL-UNNAMED
08-Apr-2021 02:41:59.051 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.util.concurrent=ALL-UNNAMED
08-Apr-2021 02:41:59.052 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
08-Apr-2021 02:41:59.052 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties
08-Apr-2021 02:41:59.052 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
08-Apr-2021 02:41:59.052 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
08-Apr-2021 02:41:59.052 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
08-Apr-2021 02:41:59.052 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
08-Apr-2021 02:41:59.052 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs=
08-Apr-2021 02:41:59.052 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/usr/local/tomcat
08-Apr-2021 02:41:59.052 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat
08-Apr-2021 02:41:59.052 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/usr/local/tomcat/temp
08-Apr-2021 02:41:59.056 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent Loaded Apache Tomcat Native library [1.2.27] using APR version [1.6.5].
08-Apr-2021 02:41:59.056 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true], UDS [true].
08-Apr-2021 02:41:59.059 INFO [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL 1.1.1d 10 Sep 2019]
08-Apr-2021 02:41:59.312 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
08-Apr-2021 02:41:59.331 INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [441] milliseconds
08-Apr-2021 02:41:59.369 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
08-Apr-2021 02:41:59.370 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/10.0.5]
08-Apr-2021 02:41:59.377 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
08-Apr-2021 02:41:59.392 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [61] milliseconds
kind: ConfigMap
apiVersion: v1
metadata:
name: rest-service
namespace: system-server
data:
application.yaml: |-
greeting:
message: Say Hello to the World
---
spring:
profiles: dev
greeting:
message: Say Hello to the Developers
---
spring:
profiles: test
greeting:
message: Say Hello to the Test
---
spring:
profiles: prod
greeting:
message: Say Hello to the Prod
kubectl edit cm rest-service -n system-server
2021-11-29 07:59:52.860:152 [OkHttp https://10.16.0.1/...] INFO org.springframework.cloud.kubernetes.config.reload.EventBasedConfigurationChangeDetector -Detected change in config maps
2021-11-29 07:59:52.862:74 [OkHttp https://10.16.0.1/...] INFO org.springframework.cloud.kubernetes.config.reload.EventBasedConfigurationChangeDetector -Reloading using strategy: REFRESH
2021-11-29 07:59:53.444:112 [OkHttp https://10.16.0.1/...] INFO org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration -Located property source: [BootstrapPropertySource {name='bootstrapProperties-configmap.rest-service.system-server'}]
2021-11-29 07:59:53.499:652 [OkHttp https://10.16.0.1/...] INFO org.springframework.boot.SpringApplication -The following profiles are active: kubernetes,dev
2021-11-29 07:59:53.517:652 [OkHttp https://10.16.0.1/...] INFO org.springframework.boot.SpringApplication -The following profiles are active: kubernetes,dev
2021-11-29 07:59:53.546:61 [OkHttp https://10.16.0.1/...] INFO org.springframework.boot.SpringApplication -Started application in 0.677 seconds (JVM running for 968605.422)
2021-11-29 07:59:53.553:61 [OkHttp https://10.16.0.1/...] INFO org.springframework.boot.SpringApplication -Started application in 0.685 seconds (JVM running for 968617.369)
$(service name).$(namespace).svc.cluster.local- ExternalName: Create a DNS The alias points to service name, This will prevent service name change , But it needs cooperation DNS The plug-in USES .
- ClusterIP: The default type , Used for within cluster Pod During the interview , Fixed access address provided , The default is to assign addresses automatically , You can use ClusterIP Key words are fixed IP.
- NodePort: be based on ClusterIp, For external access to the cluster Service Back Pod Provide access port .
- LoadBalancer: It is based on NodePort.
- RoundRobin: Polling mode , That is, polling forwards requests to various back-end pod On , It's the default mode .
- SessionAffinity: client-based IP Address for session hold mode , similar IP Hash The way , To achieve load balancing of services .
apiVersion: v1
kind: Service
metadata:
name: rest-service-service
namespace: system-server
spec:
type: NodePort
ports:
- name: rest-svc
port: 2001
targetPort: 2001
selector:
app: rest-service
system-server rest-service-deployment-cc7c5b559-6t4lp 1/1 Running 6 11d 10.244.0.188 leinao-deploy-server <none> <none>
system-server rest-service-deployment-cc7c5b559-gpg4m 1/1 Running 6 11d 10.244.0.189 leinao-deploy-server <none> <none>
actual combat K8s The architecture implementation of the next microservice
- Oauth2 High availability implementation
- How to access services across namespaces
- How to realize the gray scale of distributed services 、 Blue green release
Oauth2 High availability implementation of
- Obtain user information for authentication
- Pass the test token To authenticate
security:
path:
ignores: /,/index,/static/**,/css/**, /image/**, /favicon.ico, /js/**,/plugin/**,/avue.min.js,/img/**,/fonts/**
oauth2:
client:
client-id: rest-service
client-secret: rest-service-123
user-authorization-uri: ${cas-server-url}/oauth/authorize
access-token-uri: ${cas-server-url}/oauth/token
resource:
loadBalanced: true
id: rest-service
prefer-token-info: true
token-info-uri: ${cas-server-url}/oauth/check_token
#user-info-uri: ${cas-server-url}/api/v1/user
authorization:
check-token-access: ${cas-server-url}/oauth/check_token




apiVersion: apps/v1
kind: Deployment
metadata:
name: cas-server-deployment
namespace: system-server
labels:
app: cas-server
spec:
replicas: 3
selector:
matchLabels:
app: cas-server
template:
metadata:
labels:
app: cas-server
spec:
nodeSelector:
cas-server: "true"
containers:
- name: cas-server
image: {{ cluster_cfg['cluster']['docker-registry']['prefix'] }}cas-server
imagePullPolicy: Always
ports:
- name: cas-server01
containerPort: 2000
volumeMounts:
- mountPath: /home/cas-server
name: cas-server-path
- mountPath: /data/cas-server
name: cas-server-log-path
- mountPath: /etc/kubernetes
name: kube-config-path
- mountPath: /abnormal_data_dir
name: abnormal-data-dir
args: ["sh", "-c", "nohup java $JAVA_OPTS -jar -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC cas-server.jar --spring.profiles.active=dev", "&"]
volumes:
- name: cas-server-path
hostPath:
path: /var/pai/cas-server
- name: cas-server-log-path
hostPath:
path: /data/cas-server
- name: kube-config-path
hostPath:
path: /etc/kubernetes
- name: abnormal-data-dir
hostPath:
path: /data/images/detect_result/defect
apiVersion: v1
kind: Service
metadata:
name: cas-server-service
namespace: system-server
spec:
ports:
- name: cas-server01
port: 2000
targetPort: cas-server01
selector:
app: cas-server
How to access services across namespaces
spring:
application:
name: cas-server
cloud:
loadbalancer:
ribbon:
enabled: false
kubernetes:
ribbon:
mode: SERVICE
discovery:
all-namespaces: true
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-loadbalancer</artifactId>
</dependency>

How to realize the gray scale of distributed services 、 Blue green release

Grayscale Publishing
apiVersion: apps/v1
kind: Deployment
metadata:
name: diff-ns-service-v1-deployment
namespace: ns-app
labels:
app: diff-ns-service
spec:
replicas: 3
selector:
matchLabels:
app: diff-ns-service
version: v1
template:
metadata:
labels:
app: diff-ns-service
version: v1
spec:
nodeSelector:
diff-ns-service: "true"
containers:
- name: diff-ns-service
image: diff-ns-service:v1
imagePullPolicy: Always
ports:
- name: diff-ns
containerPort: 2001
volumeMounts:
- mountPath: /home/diff-ns-service
name: diff-ns-service-path
- mountPath: /data/diff-ns-service
name: diff-ns-service-log-path
- mountPath: /etc/kubernetes
name: kube-config-path
- mountPath: /abnormal_data_dir
name: abnormal-data-dir
args: ["sh", "-c", "nohup java $JAVA_OPTS -jar -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC diff-ns-service.jar --spring.profiles.active=dev", "&"]
volumes:
- name: diff-ns-service-path
hostPath:
path: /var/pai/diff-ns-service
- name: diff-ns-service-log-path
hostPath:
path: /data/diff-ns-service
- name: kube-config-path
hostPath:
path: /etc/kubernetes
- name: abnormal-data-dir
hostPath:
path: /data/images/detect_result/defect
apiVersion: apps/v1
kind: Deployment
metadata:
name: diff-ns-service-v2-deployment
namespace: ns-app
labels:
app: diff-ns-service
spec:
replicas: 3
selector:
matchLabels:
app: diff-ns-service
version: v2
template:
metadata:
labels:
app: diff-ns-service
version: v2
spec:
nodeSelector:
diff-ns-service: "true"
containers:
- name: diff-ns-service
image: diff-ns-service:v2
imagePullPolicy: Always
ports:
- name: diff-ns
containerPort: 2001
volumeMounts:
- mountPath: /home/diff-ns-service
name: diff-ns-service-path
- mountPath: /data/diff-ns-service
name: diff-ns-service-log-path
- mountPath: /etc/kubernetes
name: kube-config-path
- mountPath: /abnormal_data_dir
name: abnormal-data-dir
args: ["sh", "-c", "nohup java $JAVA_OPTS -jar -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC diff-ns-service.jar --spring.profiles.active=dev", "&"]
volumes:
- name: diff-ns-service-path
hostPath:
path: /var/pai/diff-ns-service
- name: diff-ns-service-log-path
hostPath:
path: /data/diff-ns-service
- name: kube-config-path
hostPath:
path: /etc/kubernetes
- name: abnormal-data-dir
hostPath:
path: /data/images/detect_result/defect
ns-app diff-ns-service-v1-deployment-d88b9c4fd-22lgb 1/1 Running 0 12s
ns-app diff-ns-service-v1-deployment-d88b9c4fd-cgsqw 1/1 Running 0 12s
ns-app diff-ns-service-v1-deployment-d88b9c4fd-hmcbq 1/1 Running 0 12s
ns-app diff-ns-service-v2-deployment-37bf53d4b-43w23 1/1 Running 0 12s
ns-app diff-ns-service-v2-deployment-37bf53d4b-ce33g 1/1 Running 0 12s
ns-app diff-ns-service-v2-deployment-37bf53d4b-scds6 1/1 Running 0 12s
apiVersion: v1
kind: Service
metadata:
name: diff-ns-service-service
namespace: ns-app
spec:
ports:
- name: diff-ns-svc
port: 2001
targetPort: 2001
selector:
app: diff-ns-service
for i in {1..10}; do curl http://diff-ns-service-service/getservicedetail?servicename=aaa; done;
diff-ns-service-v1
diff-ns-service-v2
diff-ns-service-v1
diff-ns-service-v2
diff-ns-service-v1
diff-ns-service-v2
diff-ns-service-v1
diff-ns-service-v2
diff-ns-service-v1
diff-ns-service-v2
kubectl scale deployment/diff-ns-service-v2-deployment --replicas=4
kubectl scale deployment/diff-ns-service-v1-deployment --replicas=1
diff-ns-service-v2
diff-ns-service-v2
diff-ns-service-v1
diff-ns-service-v2
diff-ns-service-v1
diff-ns-service-v2
diff-ns-service-v2
diff-ns-service-v2
diff-ns-service-v2
diff-ns-service-v2
Blue green release
apiVersion: v1
kind: Service
metadata:
name: diff-ns-service-service
namespace: ns-app
spec:
ports:
- name: diff-ns-svc
port: 2001
targetPort: 2001
selector:
app: diff-ns-service
version: v1
for i in {1..10}; do curl http://diff-ns-service-service/getservicedetail?servicename=aaa; done;
diff-ns-service-v1
diff-ns-service-v1
diff-ns-service-v1
diff-ns-service-v1
diff-ns-service-v1
diff-ns-service-v1
diff-ns-service-v1
diff-ns-service-v1
diff-ns-service-v1
diff-ns-service-v1
kubectl patch service diff-ns-service-service -p '{"spec":{"selector":{"version":"v2"}}}'
for i in {1..10}; do curl http://diff-ns-service-service/getservicedetail?servicename=aaa; done;
diff-ns-service-v2
diff-ns-service-v2
diff-ns-service-v2
diff-ns-service-v2
diff-ns-service-v2
diff-ns-service-v2
diff-ns-service-v2
diff-ns-service-v2
diff-ns-service-v2
diff-ns-service-v2
Conclusion
Cloud native technology and micro service architecture are seamless
The future of micro services in the cloud based era
边栏推荐
- 王兴张勇徐雷,谁能问鼎本地电商?
- @EnableFeignClients注解源码解析
- 【实战】基于Chromedriver的应用及爬虫相关
- 华为十大发明公布:高效加法网络、多目标博弈智能驾驶获奖
- After 4 years of experience, I have interviewed 20K test posts. I can't even master basic skills. It's better to recruit fresh students
- 程序员高考卷曝光,你能得多少分?
- JS实现复制内容到剪贴板的方法
- JS事件流、事件冒泡、阻止冒泡、事件捕获(一看就懂)
- js项目中常用的一些工具函数
- 薪酬不變,每周只上四天班,英國試行全球最大規模“四天工作制”
猜你喜欢

细说腾讯如何做到直播延时降低90%以上方案

中国加密艺术师孟晓峰参加意大利举办的“液态合金”元宇宙画展

Hongmeng transplants the compiling system of i.mx6ull (VII) liteos-a

How greatsql is a popular open source database in China

MySQL数据库的存储引擎

2022年6月中国数据库排行榜:TiDB卷土重来摘桂冠,达梦蛰伏五月夺探花

酒店长租是一门好生意吗?

Implementing MySQL master-slave with docker compose

GreatSQL如何做中国广受欢迎的开源数据库

技术干货 | Linkis实践:新引擎实现流程解析
随机推荐
各厂商的数据湖解决方案
CICC digital intelligence China II: five questions and five answers to database business market
Hongmeng porting i.mx6ull (11) storage device driver (based on imx6ull)
最成功也最差劲的CEO去世,索尼还是走在他的老路上
工资管理系统该如何使用?
微信小程序轮播图的代码错误写法
Qt msvc编译器中文问题解决,中文乱码以及无法正常编译
名片微信小程序错误版本2
陕西西安等保测评单位有哪些?在哪里可以查到?
新冠病毒的最终解药
自如涨价,会逼退年轻人吗?
品牌焕新、产品上新、营销创新,东风标致的向上之路.
3 个技巧来破解你可以立即使用的 Flutter 生产力!
文档编辑器
【论文】Cascade RPN: Delving into high-quality region proposal network with Adaptive Convolution
How insecure is NFT from copyright to assets?
JS事件流、事件冒泡、阻止冒泡、事件捕获(一看就懂)
Hongmeng transplants the compiling system of i.mx6ull (VII) liteos-a
China UnionPay (Cloud Computing) fixed-point services: lingqueyun, daocloud, Youyun and Boyun won the bid (Development); Shenzhou information, Tencent cloud and Xinhua three standards (transportation
详解工厂方法