2024-09-04

Redis提供了三种删除策略:

  1. 立即删除:键被立即删除,无论是否正在使用。
  2. 惰性删除:键在下次访问时检查是否需要删除,如果需要则删除。
  3. 定时删除:键在一定时间后自动删除。

这些策略是通过配置文件或者CONFIG命令设置的。

例如,使用redis-cli设置立即删除:




redis-cli config set lazyfree-lazy-eviction no
redis-cli config set lazyfree-lazy-expire no
redis-cli config set lazyfree-lazy-server-del no

使用redis-cli设置惰性删除:




redis-cli config set lazyfree-lazy-eviction yes
redis-cli config set lazyfree-lazy-expire yes
redis-cli config set lazyfree-lazy-server-del yes

注意:Redis 4.0以上版本默认启用了惰性删除,可以通过配置文件或者CONFIG命令设置定时删除的时间。

设置定时删除时间:




redis-cli config set hz 10

上面的hz配置指的是Redis的定时任务执行频率,默认为10,表示每秒钟执行10次定时任务,可以通过调整这个值来改变定时删除的时间间隔。

2024-09-04

Go语言是一种静态类型的编程语言,设计的目的是为了提高程序的可维护性和可读性。Go语言的一个主要特点是它的编译器和运行时间环境,被称为Go编译器,它可以将Go源代码编译成机器码。

在Golang中,我们可以使用多种方式来运行Go程序。以下是一些主要的方法:

  1. 使用Go命令行工具

Go语言自带了一个编译器,我们可以使用它来编译和运行Go程序。

例如,我们有一个名为hello.go的Go程序,其内容如下:




package main
 
import "fmt"
 
func main() {
    fmt.Println("Hello, World!")
}

我们可以使用以下命令来编译和运行这个程序:




go run hello.go
  1. 使用Go IDE或文本编辑器

我们可以使用像Goland,Visual Studio Code等IDE来编写和运行Go程序。

例如,在Visual Studio Code中,我们可以直接运行hello.go文件,Visual Studio Code会自动调用Go编译器来编译和运行Go程序。

  1. 使用Docker

我们也可以使用Docker来运行Go程序。

例如,我们有一个名为Dockerfile的文件,其内容如下:




FROM golang:1.16
WORKDIR /app
COPY . .
RUN go build -o myapp
CMD ["./myapp"]

我们可以使用以下命令来构建和运行Go程序:




docker build -t myapp .
docker run -it --rm --name my-running-app myapp
  1. 使用云服务

我们也可以使用像AWS Lambda,Google Cloud Functions等云服务来运行Go程序。

例如,在AWS Lambda中,我们需要创建一个ZIP包,包含我们的Go程序以及所需的依赖关系,然后将这个ZIP包上传到AWS Lambda,并设置一个触发器来运行Go程序。

总的来说,运行Go程序的方式有很多种,主要取决于你的具体需求和环境。

2024-09-04

在Spring Security和JWT结合的情况下,用户登录验证和权限授权的核心步骤如下:

  1. 用户提交登录信息,后端接收并验证。
  2. 验证成功后,生成JWT token,并移除session。
  3. 返回JWT token给客户端。
  4. 客户端将JWT token存储下来,并在后续请求中携带。
  5. 后端接收请求,解析JWT token获取用户信息。
  6. 根据用户权限配置,授予访问资源的权限。

以下是核心代码示例:

SecurityConfig.java:Spring Security配置




@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        // 其他配置
        .csrf().disable() // 禁用CSRF保护
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 无状态会话管理
        .and()
        .addFilter(new JwtAuthenticationFilter(authenticationManager())); // 添加JWT认证过滤器
}

JwtAuthenticationFilter.java:JWT认证过滤器




public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    // ...
 
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request,
                                                HttpServletResponse response) throws AuthenticationException {
        // 获取用户凭证
        // ...
 
        // 返回认证结果
        return authenticationManager.authenticate(authenticationToken);
    }
 
    @Override
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response,
                                            FilterChain chain,
                                            Authentication authentication) {
        // 生成JWT token
        String token = Jwts.builder()
            .setSubject(user.getUsername())
            .setExpiration(new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME))
            .signWith(SignatureAlgorithm.HS512, SecurityConstants.SECRET_KEY)
            .compact();
 
        // 移除session
        request.getSession().invalidate();
 
        // 添加token到响应头
        response.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token);
    }
}

SecurityConstants.java:安全常量定义




public class SecurityConstants {
    public static final long EXPIRATION_TIME = 864000000; // 10 days
    public static final String SECRET_KEY = "Your_Secret_Key";
    public static final String HEADER_STRING = "Authorization";
    public static final String TOKEN_PREFIX = "Bearer ";
}

ResourceServerConfig.java:资源服务器配置




@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
 
    @Override
   
2024-09-04

在Windows环境下部署MongoDB副本集需要以下步骤:

  1. 安装MongoDB。
  2. 配置副本集。
  3. 启动MongoDB实例。

以下是一个基本的示例:

  1. 安装MongoDB。

从官网下载MongoDB的Windows安装包,并按照指引进行安装。

  1. 配置副本集。

创建一个配置文件 replica_set.conf,例如:




{
    "_id" : "rs0",
    "members" : [
        {
            "_id" : 0,
            "host" : "localhost:27017"
        },
        {
            "_id" : 1,
            "host" : "localhost:27018"
        },
        {
            "_id" : 2,
            "host" : "localhost:27019"
        }
    ]
}
  1. 启动MongoDB实例。

分别在不同的端口上启动MongoDB实例,例如:




mongod --port 27017 --dbpath "C:\data\db0" --replSet rs0
mongod --port 27018 --dbpath "C:\data\db1" --replSet rs0
mongod --port 27019 --dbpath "C:\data\db2" --replSet rs0

确保你已经创建了相应的文件夹C:\data\db0, C:\data\db1, C:\data\db2

  1. 初始化副本集。

连接到其中一个MongoDB实例,并使用rs.initiate()命令初始化副本集:




mongo --port 27017
rs.initiate(
  {
    "_id": "rs0",
    "members": [
      { "_id": 0, "host": "localhost:27017" },
      { "_id": 1, "host": "localhost:27018" },
      { "_id": 2, "host": "localhost:27019" }
    ]
  }
)

这样,一个基本的副本集就部署完成了。你可以通过连接到任一实例来进行数据的读写,MongoDB会自动将写操作同步到其他副本集成员。

2024-09-04



import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEvent;
 
// 自定义事件类,继承 ApplicationEvent
public class CustomEvent extends ApplicationEvent {
    private String message;
 
    public CustomEvent(Object source, String message) {
        super(source);
        this.message = message;
    }
 
    public String getMessage() {
        return message;
    }
}
 
// 事件监听器,实现 ApplicationListener 接口
public class CustomEventListener implements ApplicationListener<CustomEvent> {
    @Override
    public void onApplicationEvent(CustomEvent event) {
        System.out.println("接收到事件:" + event.getMessage());
        // 处理接收到的事件
    }
}
 
// 在Spring Boot中使用ApplicationEventPublisher发布事件
@Service
public class CustomEventService {
    @Autowired
    private ApplicationEventPublisher publisher;
 
    public void publish(String message) {
        CustomEvent customEvent = new CustomEvent(this, message);
        publisher.publishEvent(customEvent);
    }
}
 
// 在Spring Boot应用中的某个位置调用publish方法发布事件
@Autowired
private CustomEventService customEventService;
 
public void someMethod() {
    customEventService.publish("发送的自定义消息内容");
}

这个代码示例展示了如何在Spring Boot项目中定义、监听和发布自定义事件。通过实现ApplicationListener接口,我们可以创建一个事件监听器来处理特定事件。通过ApplicationEventPublisher,我们可以在应用程序的任何位置发布事件。这种方式在处理异步消息和事件驱动的架构中非常有用。

2024-09-04

Spring Boot内嵌的Tomcat容器是通过Spring Framework的EmbeddedWebApplicationContext接口实现的。Spring Boot在启动时会自动配置内嵌的Tomcat容器,并将应用程序的Web组件(如DispatcherServlet)注册到这个Tomcat容器中。

以下是Spring Boot启动内嵌Tomcat容器的大致步骤:

  1. SpringBootWebApplication类中找到@SpringBootApplication注解。
  2. 根据@EnableAutoConfiguration注解自动配置条件,Spring Boot会启用相关的自动配置类,例如EmbeddedTomcat相关配置。
  3. EmbeddedTomcat配置类检测到应用程序的类路径上有Tomcat相关依赖,并创建内嵌的Tomcat服务器实例。
  4. 配置Tomcat的相关属性,如端口、应用上下文等。
  5. 启动内嵌的Tomcat服务器,监听HTTP请求。

以下是一个简化的Spring Boot启动内嵌Tomcat的代码示例:




@SpringBootApplication
public class SpringBootWebApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootWebApplication.class, args);
    }
}
 
@Configuration
@ConditionalOnClass({ Servlet.class, Tomcat.class })
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
public class EmbeddedTomcatConfiguration {
 
    @Bean
    public TomcatServletWebServerFactory tomcatServletWebServerFactory() {
        return new TomcatServletWebServerFactory();
    }
}
 
public class TomcatServletWebServerFactory {
 
    public WebServer getWebServer(ServletContextInitializer... initializers) {
        Tomcat tomcat = new Tomcat();
        // 配置Tomcat相关属性
        // ...
 
        tomcat.start();
        return new TomcatWebServer(tomcat);
    }
}

在这个示例中,SpringBootWebApplication类标记了Spring Boot应用程序的入口点。EmbeddedTomcatConfiguration配置类检测到Tomcat类存在于类路径中,并且没有用户自定义的ServletWebServerFactory,于是它创建了一个TomcatServletWebServerFactory Bean,这个Bean负责构建内嵌的Tomcat服务器,并启动它来监听HTTP请求。

2024-09-04

Oracle数据库的导入导出通常使用expdpimpdp工具,这些工具是Data Pump的一部分,它们用于执行高速数据和元数据的迁移。

导出(Export):




expdp username/password@db_link DIRECTORY=directory_name DUMPFILE=dump_file_name.dmp SCHEMAS=schema_name

导入(Import):




impdp username/password@db_link DIRECTORY=directory_name DUMPFILE=dump_file_name.dmp SCHEMAS=schema_name REMAP_SCHEMA=old_schema:new_schema TABLE_EXISTS_ACTION=replace

在这些命令中:

  • username/password:替换为你的数据库用户名和密码。
  • db_link:替换为你的数据库链接名称。
  • directory_name:需要是数据库目录对象,指向一个实际的文件系统目录。
  • dump_file_name.dmp:导出文件的名称。
  • schema_name:需要导入的模式名称。
  • old_schema:new_schema:当需要将对象从一个模式重新映射到另一个模式时使用。
  • TABLE_EXISTS_ACTION=replace:如果表已存在,则替换它(谨慎使用,可能会丢失数据)。

确保在执行这些命令前,数据库目录对象已正确创建,并且用户有足够的权限操作这些目录和文件。

2024-09-04

在Spring Cloud中构建微服务时,以下是一些经验分享和示例代码:

  1. 使用Spring Cloud Netflix的@EnableEurekaClient注解来标注一个服务作为Eureka客户端,并将其注册到Eureka服务器。



@SpringBootApplication
@EnableEurekaClient
public class MyServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyServiceApplication.class, args);
    }
}
  1. 使用@FeignClient注解来声明一个Feign客户端用于服务间通信。



@FeignClient("other-service")
public interface OtherServiceClient {
    @GetMapping("/endpoint")
    String getData();
}
  1. 使用Spring Cloud Config来集中管理配置。



spring.cloud.config.server.git.uri=https://github.com/your-config-repo
  1. 使用Spring Cloud Sleuth来为微服务应用添加跟踪能力。



<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
  1. 使用Spring Cloud Stream来实现消息驱动的微服务。



@EnableBinding(Sink.class)
public class MessageReceiver {
    @StreamListener(Sink.INPUT)
    public void handleMessage(String message) {
        // 处理接收到的消息
    }
}
  1. 使用Spring Cloud Gateway作为API网关。



spring:
  cloud:
    gateway:
      routes:
        - id: other_service
          uri: http://other-service
          predicates:
            - Path=/other-service/**

这些代码片段和配置提供了如何在Spring Cloud环境中使用不同的组件的简单示例。

2024-09-04

在Spring Boot中,你可以使用Spring Data MongoDB来实现分页和去重的功能。以下是一个使用MongoTemplate进行分页和去重的示例:

首先,你需要定义一个去重的查询,使用distinct方法。然后,你可以使用MongoTemplatefind方法进行分页查询,同时结合去重的结果。




import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoDatabase;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Page;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
 
import java.util.List;
 
public class MongoDbExample {
 
    public static void main(String[] args) {
        MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017");
        MongoDatabase database = mongoClient.getDatabase("yourDatabase");
        MongoTemplate mongoTemplate = new MongoTemplate(database);
 
        // 去重字段
        String distinctFieldName = "distinctField";
 
        // 分页参数
        int page = 0;
        int size = 10;
        PageRequest pageRequest = PageRequest.of(page, size);
 
        // 去重查询
        Query distinctQuery = new Query();
        distinctQuery.with(new Criteria().key(distinctFieldName));
        List<Object> distinctValues = mongoTemplate.findDistinct(collectionName, distinctFieldName, YourEntity.class, distinctQuery, Object.class);
 
        // 根据去重结果进行分页查询
        Query pageQuery = new Query();
        pageQuery.addCriteria(Criteria.where(distinctFieldName).in(distinctValues));
        Page<YourEntity> pageResult = mongoTemplate.find(pageQuery.with(pageRequest), YourEntity.class);
 
        // 处理分页结果
        List<YourEntity> content = pageResult.getContent();
 
        // 关闭客户端
        mongoClient.close();
    }
}
 
class YourEntity {
    // 实体类的字段和方法
}

在这个例子中,YourEntity是你的MongoDB文档对应的实体类。distinctFieldName是你想要去重的字段名。collectionName是存储你实体的集合名。pagesize是分页参数。

请注意,这个例子假设你已经有了Spring Data MongoDB的依赖和配置。根据你的具体需求,你可能需要调整查询条件和分页逻辑。

2024-09-04



import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.ws.client.core.WebServiceTemplate;
 
@SpringBootApplication
public class Application {
 
    @Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        // 设置WebService的包名,应与WSDL生成的包名一致
        marshaller.setContextPath("com.example.generated");
        return marshaller;
    }
 
    @Bean
    public WebServiceTemplate webServiceTemplate(Jaxb2Marshaller marshaller) {
        WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
        webServiceTemplate.setMarshaller(marshaller);
        webServiceTemplate.setUnmarshaller(marshaller);
        // 设置WebService地址
        webServiceTemplate.setDefaultUri("http://localhost:8080/ws");
        return webServiceTemplate;
    }
 
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

在这个例子中,我们创建了一个Spring Boot应用程序,并配置了WebServiceTemplate bean,该bean使用JAXB来序列化和反序列化SOAP消息。我们设置了marshaller的上下文路径,以便它知道从哪个包中查找对应的类。然后,我们设置了WebService的默认URI,这样WebServiceTemplate就知道要调用哪个服务。这个配置是在Spring Boot应用程序的主类中完成的,是Spring Boot与WebService集成的一个简单示例。