Spring Cloud Kubernetes之实战一配置管理

Spring 源码硬核解析系列专题(三十三):Spring Cloud Kubernetes 的 Kubernetes 集成源码解析 在前几期中,我们从 Spring 核心到 Spring Boot 的多个模块,再到 Spring Cloud LoadBalancer,逐步揭示了 Spring 生态在微服务领域的广泛应用。Spring Cloud Kubernetes 将 Spring Cloud 的功能扩展到 Kubernetes 平台,提供服务发现、配置管理和负载均衡等支持。本篇将深入 Spring Cloud Kubernetes 的源码,剖析其核心机制与实现原理,并补充 图示。 阅读详情

一直以来,玩springcloud的,基本都是在玩Springboot1.x,Springcloud(Dalston版)的众多相关组件来做配置中心、服务注册与发现,网关用的是Netflix公司对springboot做的LB,等等,但是这些东西太过沉重,复杂了。在一个以k8s为基础的iaas服务系统,如果不用k8s的特性来做这些事,那是说不过去的。理由这就不重复述说了。一句话:减少系统服务的复杂性。

本文主要介绍springcloud结合k8s,做配置管理,避免更多服务组件的冗余,完美填坑版!

环境:

ubuntu16.04

docker18.04

k8s1.13.x +

maven3.5.3

java1.8 +

springboot 2.1.1

spring-cloud-kubernetes:1.0.1.RELEAS
  1. 前提

    Ubuntu下安装docker18.04 or 其它较高版本,k8s1.13.x及以上,jvm环境等。
    
  2. 创建项目
    在这里插入图片描述
    在这里插入图片描述
    基础依赖:

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
        <relativePath/>
    </parent>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<swagger.version>2.6.1</swagger.version>
		<xstream.version>1.4.7</xstream.version>
		<pageHelper.version>4.1.6</pageHelper.version>
		<fastjson.version>1.2.51</fastjson.version>
		<shiro.version>1.3.0</shiro.version>
		<!-- <kubernetes-client-version>6.0.1</kubernetes-client-version> -->
		<kubernetes-client-version>5.0.0</kubernetes-client-version>
		<fabric8-kubernetes-client.version>4.6.1</fabric8-kubernetes-client.version><!-- 对应k8s v1.15.3 -->
		<springcloud.version>Greenwich.SR4</springcloud.version>
		<springcloud.kubernetes.version>1.1.1.RELEASE</springcloud.kubernetes.version>
		<mysql.version>5.1.46</mysql.version>
	</properties>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${springcloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

核心依赖:

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<exclusions>
				<exclusion>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-starter-tomcat</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-undertow</artifactId>
		</dependency>
		
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator-autoconfigure</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-kubernetes-config</artifactId>
            </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

<!-- springcloud-k8s-discovery -->
		
		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-commons</artifactId>
        </dependency>
		
		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-kubernetes-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-kubernetes-discovery</artifactId>
        </dependency>
		
		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>
        </dependency>
		
		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
    **本次依赖引入配置管理、服务的发现(即消费者)。**

如果有操作redis和db的话,引入相应的依赖:

<!-- mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql.version}</version>
		</dependency>
        
        <!--分页插件-->  
	    <dependency>
	      <groupId>com.github.pagehelper</groupId>  
	      <artifactId>pagehelper</artifactId>  
	      <version>${pageHelper.version}</version>
	    </dependency>

        <!-- datasource pool-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.3</version>
        </dependency>
        
		<dependency>
		    <groupId>org.apache.commons</groupId>
		    <artifactId>commons-lang3</artifactId>
		    </dependency>
		
		<dependency>
		    <groupId>commons-collections</groupId>
		    <artifactId>commons-collections</artifactId>
		    <version>3.2.2</version>
		</dependency>
        
        <!-- 对redis支持,引入的话项目缓存就支持redis了,所以必须加上redis的相关配置,否则操作相关缓存会报异常 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-redis</artifactId>
			<version>1.4.7.RELEASE</version>
		</dependency>
		
		<dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>19.0</version>
        </dependency> 

剩下的就是构建镜像时的插件:

<build>
		<finalName>${project.artifactId}</finalName>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
					<fork>true</fork>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.jacoco</groupId>
				<artifactId>jacoco-maven-plugin</artifactId>
				<version>0.7.8</version>
				<executions>
					<execution>
						<goals>
							<goal>prepare-agent</goal>
							<goal>report</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>

接下来,我们创建主类:

@SpringBootApplication(scanBasePackages = { "com.leinao" })
@EnableConfigurationProperties(EnvConfig.class)
@EnableDiscoveryClient
@EnableHystrix
@EnableScheduling
public class AdminApp {
	public static void main(String[] args) {
		SpringApplication.run(AdminApp.class, args);
	}
}

注意这里创建启动类时,对springboot的项目进行了优化,避免启动时加载很多,启动繁重,具体深度优化,可参考:https://mp.weixin.qq.com/s?__biz=MzU2NjIzNDk5NQ==&mid=2247487954&idx=1&sn=2426451f3bd83161cfe1237f82d6b448&key=f8fb043b3d2681a794e51a46e142af77355722dff712776af12b1f3c831218df6dfc329df63c8e5e550b3d88d58f0f178c4c3c16b141733e0e3344fa595e2bc25241d864d45132753fd99279b832de85&ascene=1&uin=MzQzMzI2NjAxMQ%3D%3D&devicetype=Windows+10&version=62070158&lang=zh_CN&pass_ticket=pnSSI9jAq0M11V5hYMmkoVm5qO%2FWk9l3UUUJMglbdtdDOzLHa7iHsDmwSzs486sD。

然后我们在进行配置,注意:据官方说,项目的src\main\resources路径下不要创建application.yml文件,只创建名为bootstrap.yml的文件:

management:
  endpoint:
    restart:
      enabled: true
    health:
      enabled: true
    info:
      enabled: true

spring:
  application:
    name: edge-admin
  cloud:
    kubernetes:
      config:
        sources:
         - name: ${spring.application.name}
           namespace: default
      discovery:
        all-namespaces: true
      reload:
        #自动更新配置的开关设置为打开
        enabled: true
        #更新配置信息的模式:polling是主动拉取,event是事件通知
        mode: polling
        #主动拉取的间隔时间是500毫秒
        period: 500
  http:
    encoding:
      charset: UTF-8
      enabled: true
      force: true
  mvc:
    throw-exception-if-no-handler-found: true
  main:
    allow-bean-definition-overriding: true # 当遇到同样名称时,是否允许覆盖注册

这里,我创建了bootstrap文件,同时也加了application文件,启动时会先加载bootstrap,验证有效。

在application.yaml中,我们加入如下内容:

server:
  port: 9999
  undertow:
    accesslog:
      enabled: false
      pattern: combined
  servlet:
    session:
      timeout: PT120M
  
logging:
  path: /data/${spring.application.name}/logs

management:
  endpoint:
    restart:
      enabled: true
    health:
      enabled: true
    info:
      enabled: true
client:
  http:
    request:
      connectTimeout: 8000
      readTimeout: 30000
      
mybatis:
  mapperLocations: classpath:mapper/*.xml
  typeAliasesPackage: com.demo.*.model
  
backend:
  ribbon:
    eureka:
      enabled: false
    client:
      enabled: true
    ServerListRefreshInterval: 5000
hystrix.command.BackendCall.execution.isolation.thread.timeoutInMilliseconds: 5000
hystrix.threadpool.BackendCallThread.coreSize: 5

注意:这里的server设置session的超时时间,对于springboot2.0与1.0版本完全不一样了,具体看内容。

其他的application-test.yaml等配置文件,配置的是日志的级别:

logging:
  level:
    com:
      leinao: INFO
    org:
      springframework:
        web: INFO

接下来配置环境配置:

EnvConfig.java类作为环境变量配置,注解ConfigurationProperties的prefix=“spring_cloud”,

表示该类用到的配置项都是名为"spring_cloud"的配置项的子内容 :

package com.demo.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * 配置信息
 * @author Damon 
 * @date 2019年10月25日 下午1:54:01
 *
 */

@Configuration
@ConfigurationProperties(prefix = "greeting")
public class EnvConfig {

    private String message = "This is a dummy message";
    
    private String container_command;
    private String model_dir_path;
    private String so_path;
    private String config_path;
    private String task_role_name;
    private String container_name;
    private String container_workdir;
    private String init_containers_image;
    private String service_account_name;
    private String spring_mq_host;
    private String spring_mq_port;
    private String spring_mq_user;
    private String spring_mq_pwd;
    private String jdbc_driverClassName;
    private String jdbc_url;
    private String jdbc_username;
    private String jdbc_password;
    private String spring_redis_host;
    private String spring_redis_port;
    private String spring_redis_pwd;
    private String kube_apiserver_address;
    private String image_path;
    private String volume_image_path;
    private String inference_job_namespace;
    private String api_version;
    private String remote_deployment_url;
    private String remote_pods_url;
    private String remote_deployment_pod_log_url;
    private String base_path;
    private String chunk_size;
    private String cas_url;
    private String create_job_url;
    private String abnormal_data_dir;
    
    private Long expire_time= 600000L;
    
    public String getMessage() {
        return this.message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

	public String getContainer_command() {
		return container_command;
	}

	public void setContainer_command(String container_command) {
		this.container_command = container_command;
	}

	public String getModel_dir_path() {
		return model_dir_path;
	}

	public void setModel_dir_path(String model_dir_path) {
		this.model_dir_path = model_dir_path;
	}

	public String getSo_path() {
		return so_path;
	}

	public void setSo_path(String so_path) {
		this.so_path = so_path;
	}

	public String getConfig_path() {
		return config_path;
	}

	public void setConfig_path(String config_path) {
		this.config_path = config_path;
	}

	public String getTask_role_name() {
		return task_role_name;
	}

	public void setTask_role_name(String task_role_name) {
		this.task_role_name = task_role_name;
	}

	public String getContainer_name() {
		return container_name;
	}

	public void setContainer_name(String container_name) {
		this.container_name = container_name;
	}

	public String getContainer_workdir() {
		return container_workdir;
	}

	public void setContainer_workdir(String container_workdir) {
		this.container_workdir = container_workdir;
	}

	public String getInit_containers_image() {
		return init_containers_image;
	}

	public void setInit_containers_image(String init_containers_image) {
		this.init_containers_image = init_containers_image;
	}

	public String getService_account_name() {
		return service_account_name;
	}

	public void setService_account_name(String service_account_name) {
		this.service_account_name = service_account_name;
	}

	public String getSpring_mq_host() {
		return spring_mq_host;
	}

	public void setSpring_mq_host(String spring_mq_host) {
		this.spring_mq_host = spring_mq_host;
	}

	public String getSpring_mq_port() {
		return spring_mq_port;
	}

	public void setSpring_mq_port(String spring_mq_port) {
		this.spring_mq_port = spring_mq_port;
	}

	public String getSpring_mq_user() {
		return spring_mq_user;
	}

	public void setSpring_mq_user(String spring_mq_user) {
		this.spring_mq_user = spring_mq_user;
	}

	public String getSpring_mq_pwd() {
		return spring_mq_pwd;
	}

	public void setSpring_mq_pwd(String spring_mq_pwd) {
		this.spring_mq_pwd = spring_mq_pwd;
	}

	public String getJdbc_driverClassName() {
		return jdbc_driverClassName;
	}

	public void setJdbc_driverClassName(String jdbc_driverClassName) {
		this.jdbc_driverClassName = jdbc_driverClassName;
	}

	public String getJdbc_url() {
		return jdbc_url;
	}

	public void setJdbc_url(String jdbc_url) {
		this.jdbc_url = jdbc_url;
	}

	public String getJdbc_username() {
		return jdbc_username;
	}

	public void setJdbc_username(String jdbc_username) {
		this.jdbc_username = jdbc_username;
	}

	public String getJdbc_password() {
		return jdbc_password;
	}

	public void setJdbc_password(String jdbc_password) {
		this.jdbc_password = jdbc_password;
	}

	public String getSpring_redis_host() {
		return spring_redis_host;
	}

	public void setSpring_redis_host(String spring_redis_host) {
		this.spring_redis_host = spring_redis_host;
	}

	public String getSpring_redis_port() {
		return spring_redis_port;
	}

	public void setSpring_redis_port(String spring_redis_port) {
		this.spring_redis_port = spring_redis_port;
	}

	public String getSpring_redis_pwd() {
		return spring_redis_pwd;
	}

	public void setSpring_redis_pwd(String spring_redis_pwd) {
		this.spring_redis_pwd = spring_redis_pwd;
	}

	public String getKube_apiserver_address() {
		return kube_apiserver_address;
	}

	public void setKube_apiserver_address(String kube_apiserver_address) {
		this.kube_apiserver_address = kube_apiserver_address;
	}

	public String getImage_path() {
		return image_path;
	}

	public void setImage_path(String image_path) {
		this.image_path = image_path;
	}

	public String getVolume_image_path() {
		return volume_image_path;
	}

	public void setVolume_image_path(String volume_image_path) {
		this.volume_image_path = volume_image_path;
	}

	public String getInference_job_namespace() {
		return inference_job_namespace;
	}

	public void setInference_job_namespace(String inference_job_namespace) {
		this.inference_job_namespace = inference_job_namespace;
	}

	public String getApi_version() {
		return api_version;
	}

	public void setApi_version(String api_version) {
		this.api_version = api_version;
	}

	public String getRemote_deployment_url() {
		return remote_deployment_url;
	}

	public void setRemote_deployment_url(String remote_deployment_url) {
		this.remote_deployment_url = remote_deployment_url;
	}

	public String getRemote_pods_url() {
		return remote_pods_url;
	}

	public void setRemote_pods_url(String remote_pods_url) {
		this.remote_pods_url = remote_pods_url;
	}

	public String getRemote_deployment_pod_log_url() {
		return remote_deployment_pod_log_url;
	}

	public void setRemote_deployment_pod_log_url(String remote_deployment_pod_log_url) {
		this.remote_deployment_pod_log_url = remote_deployment_pod_log_url;
	}

	public String getBase_path() {
		return base_path;
	}

	public void setBase_path(String base_path) {
		this.base_path = base_path;
	}

	public String getChunk_size() {
		return chunk_size;
	}

	public void setChunk_size(String chunk_size) {
		this.chunk_size = chunk_size;
	}

	public Long getExpire_time() {
		return expire_time;
	}

	public void setExpire_time(Long expire_time) {
		this.expire_time = expire_time;
	}

	public String getCas_url() {
		return cas_url;
	}

	public void setCas_url(String cas_url) {
		this.cas_url = cas_url;
	}

	public String getCreate_job_url() {
		return create_job_url;
	}

	public void setCreate_job_url(String create_job_url) {
		this.create_job_url = create_job_url;
	}

	public String getAbnormal_data_dir() {
		return abnormal_data_dir;
	}

	public void setAbnormal_data_dir(String abnormal_data_dir) {
		this.abnormal_data_dir = abnormal_data_dir;
	}
	
    
}

测试demo类:

/**
 * @author Damon 
 * @date 2019年12月27日 上午9:16:41
 *
 */

@RestController
public class DemoController {
	
	@Autowired
    private EnvConfig envConfig;
	
	/**
	 *
	 * @author Damon 
	 * @date 2019年12月26日
	 *
	 */
	
	@GetMapping(value = "/getTest")
	public String getTest() {
		return envConfig.getBase_path();
	}
}

重点:默认的svc是没有权限访问k8s的API Server的资源的,执行如下脚本,可以提升权限,允许其访问configmap的可读权限:

#使用这个代表集群最高权限,deployment中无需引入serviceAccount: config-reader
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: fabric8-rbac
subjects:
  - kind: ServiceAccount
    # Reference to upper's `metadata.name`
    name: default
    # Reference to upper's `metadata.namespace`
    namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

配置configmap:

kind: ConfigMap
apiVersion: v1
metadata:
  name: edge-admin
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

接下来就是执行deployment启动项目了:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: edge-admin-deployment
  labels:
    app: edge-admin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: edge-admin
  template:
    metadata:
      labels:
        app: edge-admin
    spec:
      nodeSelector:
        edge-admin: "true"
      containers:
      - name: edge-admin
        image: 10.11.2.20:8000/harbor/edge-admin
        imagePullPolicy: IfNotPresent
        ports:
          - name: admin01
            containerPort: 1002
        volumeMounts:
        - mountPath: /home/edge-admin
          name: edge-admin-path
        - mountPath: /data/edge-admin
          name: edge-admin-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 edge-admin.jar --spring.profiles.active=dev", "&"]
      hostAliases:
      - ip: "10.10.1.5"
        hostnames:
        - "k8s.api.server"
        - "foo.remote"
      - ip: "127.0.0.1"
        hostnames:
        - "foo.localhost"
      - ip: "0.0.0.0"
        hostnames:
        - "foo.all"
      #利用admin-rbac.yaml来获取权限
      #serviceAccount: config-reader
      #serviceAccountName: config-reader
      volumes:
      - name: edge-admin-path
        hostPath:
          path: /var/pai/edge-admin
      - name: edge-admin-log-path
        hostPath:
          path: /data/edge-admin
      - name: kube-config-path
        hostPath:
          path: /etc/kubernetes
      - name: abnormal-data-dir
        hostPath:
          path: /data/images/detect_result/defect

其中,前面说的,项目启动参数对其性能优化,是对jvm的参数设置。分别执行kubectl apply -f deployment.yaml和configmap.yaml,创建demo时所用的configmap的资源以及利用k8s部署启动项目。

最后打开浏览器:执行ip:port/hello,即可看到configmap中对应的属性值,这里就不展示了,有兴趣的可以试试。

以上即是对springcloud和k8s首次结合后利用其configmap特性,来做配置管理,摒弃springcloud-config、spring-boot-starter-actuator的组件,减少系统的复杂性,毕竟k8s是肯定会被用到的,所以可以直接用其特性来做系统服务的环境配置管理。



个人网站

技术分享博客

结束福利

开源实战利用 k8s 作微服务的架构设计代码:

https://gitee.com/damon_one/spring-cloud-k8s

欢迎大家 star,多多指教。


关于作者

  笔名:Damon,技术爱好者,长期从事 Java 开发、Spring Cloud 的微服务架构设计,以及结合docker、k8s做微服务容器化,自动化部署等一站式项目部署、落地。Go 语言学习,k8s研究,边缘计算框架 KubeEdge 等。公众号 程序猿Damon 发起人。个人微信 MrNull008,欢迎來撩。


欢迎关注 InfoQ: https://www.infoq.cn/profile/1905020/following/user

欢迎关注

Java开发:Spring Cloud与Kubernetes的协同工作 在当今的软件开发领域,微服务架构已经成为主流的架构模式。Spring Cloud是为开发微服务提供的一套工具集,而Kubernetes是一个强大的容器编排和管理平台。本文章的目的在于深入探讨如何让Spring Cloud和Kubernetes协同工作,以发挥它们各自的优势,构建更加高效、稳定和可扩展的微服务系统。范围涵盖了从核心概念的理解、算法原理的剖析、实际项目的开发,到应用场景的分析以及未来发展趋势的探讨。 阅读详情

相关推荐

Spring Cloud Gateway:Actuator API(执行器API)

/gateway执行器端点允许您监视和与Spring Cloud Gateway应用程序进行交互。为了远程访问,该端点必须在应用程序属性中启用并通过HTTP或JMX公开。

专注于深入研究多种编程语言,以实战为导向,逐步拓展开发技能,提升工程化编码和思维能力,展现无敌技术实力。 1909

Spring Cloud Gateway 微服务网关

Spring Cloud Gateway 微服务网关 创建项目(命名 为 Gateway), 添加pom 依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId&...

Dong滴个Dong的博客 3016

Spring Cloud Gateway 监控、多网关实例路由共享 | Spring Cloud 18

Actuator是Spring Boot提供的用来对应用系统进行监控的功能模块,借助于Actuator开发者可以很方便地对应用系统某些监控指标进行查看、统计等。 Actuator的核心是端点Endpoint。 Endpoint可以让我们监视应用程序并与其交互。Spring Boot包含许多内置端点,并允许您添加自己的端点。 我们可以启用或禁用每个端点,启用或禁用端点控制是否创建端点并且其bean存在于应用程序上下文中。 要进行远程访问,还必须通过JMX或HTTP公开端点。大多数端点HTTP访问默认是关闭的。

gmHappy 6441

SpringCloud:Spring Cloud Gateway中如何配置LoadBalancer

要在Spring-Cloud-Gateway中配置LoadBalancer,需要用到spring-cloud-starter-netflix-ribbon,因此需要将它引入。 pom.xml: java代码: import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframewor

2136

Spring Cloud Kubernetes 服务注册与发现详解

在云原生时代,Spring Cloud 与 Kubernetes 的深度集成成为微服务架构发展的必然趋势。Spring Cloud Kubernetes 作为连接 Spring Cloud 与 Kubernetes 的桥梁,为微服务应用提供了强大的服务注册与发现、配置管理、动态扩缩容等功能。本文将深入探讨 Spring Cloud Kubernetes 的核心概念、服务注册与发现的实现原理及实践操作,结合代码示例和实际应用场景,帮助读者全面掌握在 Kubernetes 环境中如何高效地进行服务治理。

加入“Super Entity”,与全能开发团队共探AI智能体与数字人项目,开启前沿技术之旅。 1440

Java配置管理的“量子纠缠”:从暗物质到全息投影——17种配置黑洞坍缩实战!

本文介绍了多种配置管理工具及其在Java应用中的实现方式。首先,Spring Cloud Config通过集中式配置管理实现“量子纠缠态”配置,客户端通过接口获取配置。其次,Kubernetes的ConfigMap和Secret分别用于存储非敏感和敏感配置,并通过环境变量或挂载方式读取。Helm Charts通过模板化配置实现动态渲染,Ansible则通过剧本驱动配置生成。HashiCorp Vault用于加密存储敏感数据,Envoy Proxy在服务网格中管理流量策略和路由规则。最后,Prometheus

墨夶的博客 791

SpringCloud-gateway Redis动态路由及 各EndPoint介绍

Spring Cloud Gateway 微服务网关 创建项目(命名 为 Gateway), 添加pom 依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> <version>2.2.0.RELEASE</version> &

z69183787的专栏 3045

加密视频如何破解 如何解除机器码绑定的视频

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 如何破解加密...

Q-980767270的博客 5万+

Spring Cloud Kubernetes实战之配置管理(附代码实现)

一直以来,玩springcloud的,基本都是在玩Springboot1.x,Springcloud(Dalston版)的众多相关组件来做配置中心、服务注册与发现,网关用的是Netflix公司对springboot做的LB,等等,但是这些东西太过沉重,复杂了。在一个以k8s为基础的iaas服务系统,如果不用k8s的特性来做这些事,那是说不过去的。理由这就不重复述说了。一句话:减少系统服务的复杂性。 本文主要介绍springcloud结合k8s,做配置管理,避免更多服务组件的冗余。 实战 环境: ubunt

诗与远方的博客 668

Design Compiler时序约束实战:如何用set_clock_uncertainty解决时钟抖动问题?

本文深入探讨了在Design Compiler时序约束实战中,如何精准运用set_clock_uncertainty命令解决时钟抖动等非理想性问题。文章详细解析了该命令在时钟树综合前后的不同应用策略、建立时间与保持时间的差异化设置,并对比了其与set_clock_jitter的适用场景,旨在帮助数字IC设计工程师制定稳健的时序约束,为后端物理实现预留合理的安全裕量,从而高效达成时序收敛。

weixin_29196891的博客 300

逆向实战:基于内存态匿名段分析的 DexProtector 检测绕过策略

本文深入探讨了针对DexProtector加固方案的Frida检测绕过策略。通过分析运行时动态加载到匿名内存段的核心检测逻辑,提出了一套基于内存态分析、定位并转储匿名可执行段,进而通过精准Hook与“等式化替换”等技术实现稳定绕过的实战方法。该方法不仅适用于DexProtector,也对采用类似内存隐藏技术的加固方案具有参考价值。

ik678901的博客 515

干货!用Spring Cloud+K8S搞定微服务项目实战!

前几天晚上加班到快十一点,我在公司楼下抽烟,跟我们组的小李聊起最近的项目,说实话那一刻我挺有感触的。我们这个系统啊,一开始是用传统的 Spring Boot 单体架构跑起来的,后来业务越来越多,接口调用越来越复杂,测试环境都能卡得半死。比如服务之间相互依赖严重,A 调 B,B 又调 C,结果链路一长,问题就复杂得要死。总结下来一句话:Spring Cloud 解决的是微服务开发层面的问题,K8S 解决的是运维和部署层面的问题。但当服务动不动就十几个模块,甚至几十个模块的时候,问题就来了:。

m0_73735578的博客 476

三菱FX5U PLC与CCLINK模块通信配置全流程(附接线图与参数详解)

本文详细解析了三菱FX5U PLC与CCLINK模块的通信配置全流程,包括硬件接线规范、参数设置及软件编程方法。通过实战指南帮助工程师快速掌握FX5U与CCLINK模块的高效通信技术,提升工业自动化控制系统的稳定性和可靠性。

weixin_27014595的博客 434

Git+Jenkins+Kubernetes+Harbor+consul+SpringCloud

 目的:学习、实践K8S   各组件介绍: 1. git  无 2. Harbor当镜像仓库,如果你的k8s master slave在一台机器上则不用搭建 3. jenkins 做CI CD,从GIT拉取代码,打包,生成docker镜像、推送Harbor仓库,然后deploy服务到k8s 4. consul 用来做服务发现注册中心和配置中心 5. springcloud 做2个...

babyck的博客 896

Qi标准下的充电协议及其记忆技巧

记忆无线充电协议中的。

m0_73991989的博客 1320

Android 系统状态栏中实现高斯模糊背景

至此,我们已经完成了在 Android 系统的 SystemUI 中实现高斯模糊背景的过程。通过以上的布局和代码修改,我们可以在状态栏中看到具有高斯模糊效果的背景。同时,为了在不同版本的 Android 系统上适配高斯模糊效果,可能需要进行一些额外的代码调整和兼容性处理。希望本文能够帮助你理解如何在 Android 系统的 SystemUI 中实现高斯模糊背景,并通过提供的源代码进行相应的开发和调试。首先,我们需要在 SystemUI 的布局文件中添加一个用于展示高斯模糊背景的视图。属性来开启模糊效果。

CyberSparkZ的博客 870

Spring Cloud微服务在Kubernetes的实战部署指南

还在为微服务集群的复杂部署而头疼吗?面对服务发现、配置管理、监控告警这些难题,很多开发者都感到无从下手。本文将为你揭秘如何将Pig-Mesh微服务架构完美部署到Kubernetes环境,提供从零开始的完整解决方案。 ## 为什么微服务部署如此困难? 在传统的单体应用向微服务架构转型的过程中,开发者常常会遇到这些痛点: **🔴 服务发现混乱** - 服务间调用需要手动配置IP地址,服务上下线

gitblog_00400的博客 937

Raspberry Pi 4B 蓝牙串口(SPP)配置与使用

Linux、Android、Windows 等操作系统带有在引导期间启动的蓝牙守护进程/蓝牙服务。 对于与监视器连接并使用 GUI(如 GTK 等)运行的设备,只需多次单击即可轻松启用并连接到附近的设备。 但是在无头设备的情况下,我们必须依赖于需要在命令行上运行的不同命令。 这篇博客我们将讨论如何在无头树莓派上通过蓝牙设备连接附近。

视觉与物联智能 2745

微服务架构中的Spring Cloud与Kubernetes集成实战

Spring Cloud提供了一系列工具来简化分布式系统的开发,包括服务发现(Eureka)、配置中心(Config)、负载均衡(Ribbon)等。它为微服务架构提供了完整的解决方案。Spring Cloud与Kubernetes的结合为微服务架构提供了强大的支持。通过本文的实战案例,读者可以掌握其核心技术与最佳实践,从而在实际项目中高效应用。

intwei的博客 329

QGC4.0.11界面修改

QGC4.0.11。

超维空间科技的博客 2466

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Spring Cloud 2023 新特性与实践

Spring Cloud 2023 带来了许多新特性和改进,特别是在服务发现、配置管理、网关和负载均衡方面。在实际项目中,我们可以根据具体场景选择合适的组件和配置,构建更加可靠、高效的微服务架构。

alex_goden的博客 4021

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

微服务与云原生架构实战指南

微服务架构将单体应用拆分为松耦合的独立服务,每个服务可独立开发、部署和扩展。云原生以容器化、动态编排(如Kubernetes)、DevOps和微服务为核心,提升系统的弹性和可观测性。Spring Cloud Alibaba提供微服务治理能力,而Kubernetes负责容器编排,两者结合可实现完整的云原生技术栈。

rZRgdVhOrU的博客 992

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

B2B电商平台Java面试:微服务与Git实战深度解析

本文以B2B电商平台Java开发工程师面试为背景,通过面试官与程序员小润龙的对话,深度解析了微服务与云原生技术栈(Spring Cloud、OpenFeign、Resilience4j、Kubernetes Client、gRPC)以及Git版本控制在实际业务场景中的应用。文章涵盖了从基础概念到高级优化策略,并提供了详细的技术知识点详解与代码示例,为读者提供一份兼具专业性、实用性和趣味性的技术学习材料。

2303_76177839的博客 542

《Java微服务架构基于SpringCloud构建高可用分布式系统的实战探索》

服务注册与发现(Eureka/ZooKeeper对比)、智能路由(Ribbon负载均衡策略)、断路器模式(Hystrix原理优化)。云原生时代对系统高可用性与可扩展性的挑战,传统单体架构局限性分析,Spring Cloud生态在分布式领域地位。注:实际内容需结合具体实验数据、算法推导与代码实现填充,此结构符合学术论文逻辑闭环要求。#### 6.3 技术边界与未来方向(Service Mesh、可观测性)4. 与题目的实战探索主题强相关,覆盖架构设计、技术选型、工程验证全链条。

wbFmioIp的博客 459

每天一道面试题之架构篇|分布式微服务架构深度剖析与实战指南

微服务架构面临服务治理、分布式事务、链路追踪等八大核心挑战。文章详细分析了这些难点,并给出技术解决方案:通过服务注册发现实现动态管理,采用同步(REST/Feign)和异步(RabbitMQ)通信模式,结合熔断降级(CircuitBreaker)保障系统稳定性。代码示例展示了服务注册、发现及通信的具体实现,为构建可靠分布式系统提供实践参考。

weixin_42326548的博客 819

好玩的spring-cloud-kubernetes 2.* 手把手入门

根据spring官方文档以及例子,通过minikube搭建简单的k8s集群手把手完成实验

weixin_43600770的博客 714
上一篇: 论Http、Socket、WebSocket、WebService(SOAP)之间的区别
下一篇: 今天被问微服务,这几点,让面试官刮目相看
交个朋友之猿田地
博客等级 码龄15年 15粉丝 53原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值